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" );
1034 if( CurTok() != T_LEFT )
1037 if( NextTok() != T_kicad_pcb)
1055 std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
1060 Unexpected( token );
1062 if( token != T_LEFT )
1063 Expecting( T_LEFT );
1084 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
1094 textItem->ResolveFont( embeddedFonts );
1124 std::map<wxString, wxString> properties;
1138 std::vector<BOARD_ITEM*> bulkAddedItems;
1141 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1145 if( token != T_LEFT )
1146 Expecting( T_LEFT );
1157 m_board->SetGenerator( FromUTF8() );
1168 m_board->SetGenerator( FromUTF8() );
1172 case T_generator_version:
1226 m_board->m_LegacyNetclassesLoaded =
true;
1236 case T_gr_ellipse_arc:
1239 bulkAddedItems.push_back( item );
1245 bulkAddedItems.push_back( item );
1251 bulkAddedItems.push_back( item );
1257 bulkAddedItems.push_back( item );
1263 bulkAddedItems.push_back( item );
1269 bulkAddedItems.push_back( item );
1275 bulkAddedItems.push_back( item );
1282 bulkAddedItems.push_back( item );
1289 bulkAddedItems.push_back( track );
1298 bulkAddedItems.push_back( arc );
1318 bulkAddedItems.push_back( item );
1335 bulkAddedItems.push_back( item );
1342 bulkAddedItems.push_back( item );
1348 bulkAddedItems.push_back( item );
1351 case T_embedded_fonts:
1358 case T_embedded_files:
1361 embeddedFilesParser.SyncLineReaderWith( *
this );
1375 for(
int tok = embeddedFilesParser.NextTok();
1377 tok = embeddedFilesParser.NextTok() )
1381 else if( tok ==
DSN_RIGHT && --depth < 0 )
1386 SyncLineReaderWith( embeddedFilesParser );
1392 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
1397 if( bulkAddedItems.size() > 0 )
1398 m_board->FinalizeBulkAdd( bulkAddedItems );
1400 m_board->SetProperties( properties );
1409 static_cast<PCB_BARCODE*
>( bc_item )->AssembleBarcode();
1414 for(
BOARD_ITEM* bc_item : fp->GraphicalItems() )
1417 static_cast<PCB_BARCODE*
>( bc_item )->AssembleBarcode();
1424 wxString msg, undefinedLayerNames, destLayerName;
1428 if( !undefinedLayerNames.IsEmpty() )
1429 undefinedLayerNames += wxT(
", " );
1431 undefinedLayerNames += layerName;
1434 destLayerName =
m_board->GetLayerName( destLayer );
1438 msg.Printf(
_(
"Items found on undefined layers (%s).\n"
1439 "Do you wish to rescue them to the %s layer?\n"
1441 "Zones will need to be refilled." ),
1442 undefinedLayerNames, destLayerName );
1453 const auto visitItem = [&](
BOARD_ITEM& curr_item )
1455 LSET layers = curr_item.GetLayerSet();
1457 if( !layers.test(
Rescue ) )
1460 layers.
set( destLayer );
1465 if( layers.count() == 1 )
1466 curr_item.SetLayer( destLayer );
1468 curr_item.SetLayerSet( layers );
1481 via->LayerPair( &top_layer, &bottom_layer );
1485 if( top_layer ==
Rescue )
1488 if( bottom_layer ==
Rescue )
1489 bottom_layer =
B_Cu;
1491 via->SetLayerPair( top_layer, bottom_layer );
1496 visitItem( *track );
1504 visitItem( *drawing );
1508 for(
BOARD_ITEM* drawing : fp->GraphicalItems() )
1509 visitItem( *drawing );
1514 for(
PCB_FIELD* field : fp->GetFields() )
1515 visitItem( *field );
1525 THROW_IO_ERRORF(
_(
"One or more items were found on undefined layers (%s). Open the board in the "
1526 "PCB Editor to resolve." ),
1527 undefinedLayerNames );
1537 ZONE* z =
static_cast<ZONE*
>( zone );
1549 for(
int i = 0; i < 2; ++i )
1551 const KIID& original = net->GetTerminalPadUuid( i );
1558 net->SetTerminalPadUuid( i, it->second );
1563 net->ResolveTerminalPads(
m_board );
1572 BOARD* board =
dynamic_cast<BOARD*
>( aParent );
1577 std::unordered_map<KIID, BOARD_ITEM*> fpItemMap;
1584 fpItemMap.insert( { child->
m_Uuid, child } );
1595 auto it = cache.find( aId );
1597 return it != cache.end() ? it->second :
nullptr;
1599 else if( footprint )
1601 auto it = fpItemMap.find( aId );
1603 return it != fpItemMap.end() ? it->second :
nullptr;
1614 std::vector<const GROUP_INFO*> groupTypeObjects;
1617 groupTypeObjects.emplace_back( &groupInfo );
1620 groupTypeObjects.emplace_back( &genInfo );
1622 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1634 THROW_IO_ERRORF(
_(
"Cannot create generated object of type '%s'" ), genInfo->genType );
1642 group->SetName( groupInfo->name );
1645 group->SetUuidDirect( groupInfo->uuid );
1647 if( groupInfo->libId.IsValid() )
1648 group->SetDesignBlockLibId( groupInfo->libId );
1650 if( groupInfo->locked )
1651 group->SetLocked(
true );
1659 fpItemMap.insert( {
group->m_Uuid,
group } );
1667 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1671 for(
const KIID& aUuid : groupInfo->memberUuids )
1678 item = getItem( aUuid );
1684 group->AddItem( item );
1690 for(
BOARD_ITEM* item : gen->GetBoardItems() )
1694 gen->SetLayer( track->GetLayer() );
1704 m_board->GroupsSanityCheck(
true );
1710 wxCHECK_RET( CurTok() == T_kicad_pcb,
1711 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
1717 if( tok == T_version )
1739 wxCHECK_RET( CurTok() == T_general,
1740 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a general section." ) );
1744 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1746 if( token != T_LEFT )
1747 Expecting( T_LEFT );
1758 case T_legacy_teardrops:
1763 while( ( token = NextTok() ) != T_RIGHT )
1765 if( !IsSymbol( token ) && token != T_NUMBER )
1766 Expecting(
"symbol or number" );
1775 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200119 ) || CurTok() == T_paper,
1776 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
1783 wxString pageType = FromUTF8();
1785 if( !pageInfo.
SetType( pageType ) )
1788 err.Printf(
_(
"Page type '%s' is not valid." ), FromUTF8() );
1815 if( token == T_portrait )
1820 else if( token != T_RIGHT )
1822 Expecting(
"portrait|)" );
1825 m_board->SetPageSettings( pageInfo );
1831 wxCHECK_RET( CurTok() == T_title_block,
1832 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as TITLE_BLOCK." ) );
1837 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1839 if( token != T_LEFT )
1840 Expecting( T_LEFT );
1853 titleBlock.
SetDate( FromUTF8() );
1868 int commentNumber =
parseInt(
"comment" );
1870 switch( commentNumber )
1919 err.Printf( wxT(
"%d is not a valid title block comment number" ), commentNumber );
1927 Expecting(
"title, date, rev, company, or comment" );
1933 m_board->SetTitleBlock( titleBlock );
1942 std::string userName;
1944 bool isVisible =
true;
1948 if( CurTok() != T_LEFT )
1949 Expecting( T_LEFT );
1952 int layer_num =
parseInt(
"layer index" );
1954 NeedSYMBOLorNUMBER();
1963 if( token == T_hide )
1968 else if( token == T_STRING )
1970 userName = CurText();
1973 else if( token != T_RIGHT )
1975 Expecting(
"hide, user defined name, or )" );
1978 aLayer->
m_type = LAYER::ParseType( type.c_str() );
1998 int dielectric_idx = 1;
2006 std::set<PCB_LAYER_ID> seenBrdLayers;
2007 bool duplicatedStackup =
false;
2009 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2011 if( CurTok() != T_LEFT )
2012 Expecting( T_LEFT );
2016 if( token != T_layer )
2020 case T_copper_finish:
2026 case T_edge_plating:
2032 case T_dielectric_constraints:
2038 case T_edge_connector:
2042 if( token == T_yes )
2044 else if( token == T_bevelled )
2050 case T_castellated_pads:
2078 layerId = candidate;
2094 else if( !( layerId & 1 ) )
2097 std::unique_ptr<BOARD_STACKUP_ITEM> itemOwner;
2100 if( layerId !=
UNDEFINED_LAYER && !seenBrdLayers.insert( layerId ).second )
2101 duplicatedStackup =
true;
2109 static constexpr int MAX_STACKUP_ITEMS = 128;
2111 itemOwner = std::make_unique<BOARD_STACKUP_ITEM>( type );
2112 item = itemOwner.get();
2118 if( !duplicatedStackup && stackup.
GetCount() < MAX_STACKUP_ITEMS )
2119 stackup.
Add( itemOwner.release() );
2123 Expecting(
"layer_name" );
2126 bool has_next_sublayer =
true;
2127 int sublayer_idx = 0;
2129 wxString specFreqUnits;
2130 wxString dielectricModel;
2132 while( has_next_sublayer )
2134 has_next_sublayer =
false;
2136 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2138 if( token == T_addsublayer )
2140 has_next_sublayer =
true;
2144 if( token == T_LEFT )
2160 if( token == T_LEFT )
2163 if( token == T_locked )
2186 case T_loss_tangent:
2192 case T_spec_frequency:
2198 case T_dielectric_model:
2207 case T_djordjevic_sarkar:
2212 Expecting(
"constant or djordjevic_sarkar" );
2233 wxColour wx_color = color.
ToColour();
2236 name.Printf( wxT(
"#%02X%02X%02X%02X" ),
2256 if( has_next_sublayer )
2265 if( token != T_RIGHT )
2271 m_board->GetDesignSettings().m_HasStackup =
true;
2282 aMap[
"Adesivo.Retro"] =
"B.Adhes";
2283 aMap[
"Adesivo.Fronte"] =
"F.Adhes";
2284 aMap[
"Pasta.Retro"] =
"B.Paste";
2285 aMap[
"Pasta.Fronte"] =
"F.Paste";
2286 aMap[
"Serigrafia.Retro"] =
"B.SilkS";
2287 aMap[
"Serigrafia.Fronte"] =
"F.SilkS";
2288 aMap[
"Maschera.Retro"] =
"B.Mask";
2289 aMap[
"Maschera.Fronte"] =
"F.Mask";
2290 aMap[
"Grafica"] =
"Dwgs.User";
2291 aMap[
"Commenti"] =
"Cmts.User";
2292 aMap[
"Eco1"] =
"Eco1.User";
2293 aMap[
"Eco2"] =
"Eco2.User";
2294 aMap[
"Contorno.scheda"] =
"Edge.Cuts";
2297 aMap[
"Kleju_Dolna"] =
"B.Adhes";
2298 aMap[
"Kleju_Gorna"] =
"F.Adhes";
2299 aMap[
"Pasty_Dolna"] =
"B.Paste";
2300 aMap[
"Pasty_Gorna"] =
"F.Paste";
2301 aMap[
"Opisowa_Dolna"] =
"B.SilkS";
2302 aMap[
"Opisowa_Gorna"] =
"F.SilkS";
2303 aMap[
"Maski_Dolna"] =
"B.Mask";
2304 aMap[
"Maski_Gorna"] =
"F.Mask";
2305 aMap[
"Rysunkowa"] =
"Dwgs.User";
2306 aMap[
"Komentarzy"] =
"Cmts.User";
2307 aMap[
"ECO1"] =
"Eco1.User";
2308 aMap[
"ECO2"] =
"Eco2.User";
2309 aMap[
"Krawedziowa"] =
"Edge.Cuts";
2312 aMap[
"Dessous.Adhes"] =
"B.Adhes";
2313 aMap[
"Dessus.Adhes"] =
"F.Adhes";
2314 aMap[
"Dessous.Pate"] =
"B.Paste";
2315 aMap[
"Dessus.Pate"] =
"F.Paste";
2316 aMap[
"Dessous.SilkS"] =
"B.SilkS";
2317 aMap[
"Dessus.SilkS"] =
"F.SilkS";
2318 aMap[
"Dessous.Masque"] =
"B.Mask";
2319 aMap[
"Dessus.Masque"] =
"F.Mask";
2320 aMap[
"Dessin.User"] =
"Dwgs.User";
2321 aMap[
"Contours.Ci"] =
"Edge.Cuts";
2327 wxCHECK_RET( CurTok() == T_layers,
2328 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layers." ) );
2333 int copperLayerCount = 0;
2335 bool anyHidden =
false;
2337 std::unordered_map< std::string, std::string > v3_layer_names;
2338 std::vector<LAYER> cu;
2343 std::vector<LAYER> appendedLayers;
2347 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2354 cu.push_back( layer );
2367 for(
size_t i = 1; i < cu.size() - 1; i++ )
2372 tmpLayer = ( i + 1 ) * 2;
2374 cu[i].m_number = tmpLayer;
2377 cu[0].m_number =
F_Cu;
2378 cu[cu.size()-1].m_number =
B_Cu;
2380 for(
auto& cu_layer : cu )
2382 enabledLayers.
set( cu_layer.m_number );
2384 if( cu_layer.m_visible )
2385 visibleLayers.
set( cu_layer.m_number );
2399 appendedLayers.push_back( cu_layer );
2402 copperLayerCount = cu.size();
2406 while( token != T_RIGHT )
2412 auto new_layer_it = v3_layer_names.find( layer.
m_name.ToStdString() );
2414 if( new_layer_it != v3_layer_names.end() )
2419 THROW_IO_ERRORF(
_(
"Layer '%s' in file '%s' at line %d is not in fixed layer hash." ),
2420 layer.
m_name, CurSource(), CurLineNumber(), CurOffset() );
2427 layer.
m_name = it->first;
2439 m_board->SetLayerDescr( it->second, layer );
2441 appendedLayers.push_back( layer );
2445 if( token != T_LEFT )
2452 if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
2454 wxString err = wxString::Format(
_(
"%d is not a valid layer count" ), copperLayerCount );
2461 m_board->SetCopperLayerCount( std::max( copperLayerCount,
m_board->GetCopperLayerCount() ) );
2462 m_board->SetEnabledLayers( enabledLayers |
m_board->GetEnabledLayers() );
2466 m_board->SetCopperLayerCount( copperLayerCount );
2467 m_board->SetEnabledLayers( enabledLayers );
2472 m_board->m_LegacyVisibleLayers = visibleLayers;
2481 const LSET& aDestInitialEnabled,
int aDestInitialCopperCount )
2485 int srcCopperCount = 0;
2486 bool mismatch =
false;
2488 for(
const LAYER& src : aSourceLayers )
2495 if( !aDestInitialEnabled.
Contains(
id ) )
2497 else if( !src.m_userName.IsEmpty() && src.m_userName !=
m_board->GetLayerName(
id ) )
2504 std::vector<INPUT_LAYER_DESC> descs;
2506 for(
const LAYER& src : aSourceLayers )
2509 desc.
Name = src.m_userName.IsEmpty() ? src.m_name : src.m_userName;
2528 descs.push_back( desc );
2534 if( progressWindow )
2535 progressWindow->Hide();
2539 if( progressWindow )
2540 progressWindow->Show();
2544 for(
const LAYER& src : aSourceLayers )
2546 wxString key = src.m_userName.IsEmpty() ? src.m_name : src.m_userName;
2547 auto it = remap.find( key );
2564 if( !aDestInitialEnabled.
Contains( target ) )
2568 m_board->SetLayerDescr( target, descr );
2571 enabled.
set( target );
2574 m_board->SetEnabledLayers( enabled );
2580 LSET_MAP::const_iterator it = aMap.find( curText );
2582 if( it == aMap.end() )
2592 LAYER_ID_MAP::const_iterator it = aMap.find( curText );
2594 if( it == aMap.end() )
2601 if( it->second ==
Rescue )
2611 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layer." ) );
2625 wxCHECK_MSG( CurTok() == T_layers,
LSET(),
2626 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as item layers." ) );
2630 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
2644 Expecting(
"single copper layer" );
2647 Expecting(
"max one soldermask layer" );
2652 Expecting(
"no mask layer when track is on internal layer" );
2656 Expecting(
"copper and mask on the same side" );
2659 Expecting(
"copper and mask on the same side" );
2667 wxCHECK_RET( CurTok() == T_setup,
2668 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as setup." ) );
2678 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
2680 if( token != T_LEFT )
2681 Expecting( T_LEFT );
2694 case T_last_trace_width:
2699 case T_user_trace_width:
2710 m_board->m_LegacyDesignSettingsLoaded =
true;
2715 case T_trace_clearance:
2716 defaultNetClass->SetClearance(
parseBoardUnits( T_trace_clearance ) );
2717 m_board->m_LegacyDesignSettingsLoaded =
true;
2721 case T_zone_clearance:
2723 m_board->m_LegacyDesignSettingsLoaded =
true;
2727 case T_zone_45_only:
2729 m_board->m_LegacyDesignSettingsLoaded =
true;
2733 case T_clearance_min:
2735 m_board->m_LegacyDesignSettingsLoaded =
true;
2741 m_board->m_LegacyDesignSettingsLoaded =
true;
2747 m_board->m_LegacyDesignSettingsLoaded =
true;
2753 m_board->m_LegacyDesignSettingsLoaded =
true;
2757 case T_via_min_annulus:
2759 m_board->m_LegacyDesignSettingsLoaded =
true;
2763 case T_via_min_size:
2765 m_board->m_LegacyDesignSettingsLoaded =
true;
2769 case T_through_hole_min:
2771 m_board->m_LegacyDesignSettingsLoaded =
true;
2776 case T_via_min_drill:
2778 m_board->m_LegacyDesignSettingsLoaded =
true;
2782 case T_hole_to_hole_min:
2784 m_board->m_LegacyDesignSettingsLoaded =
true;
2801 m_board->m_LegacyDesignSettingsLoaded =
true;
2808 m_board->m_LegacyDesignSettingsLoaded =
true;
2814 m_board->m_LegacyDesignSettingsLoaded =
true;
2818 case T_uvias_allowed:
2820 m_board->m_LegacyDesignSettingsLoaded =
true;
2824 case T_blind_buried_vias_allowed:
2826 m_board->m_LegacyDesignSettingsLoaded =
true;
2830 case T_uvia_min_size:
2832 m_board->m_LegacyDesignSettingsLoaded =
true;
2836 case T_uvia_min_drill:
2838 m_board->m_LegacyDesignSettingsLoaded =
true;
2842 case T_user_diff_pair:
2852 m_board->m_LegacyDesignSettingsLoaded =
true;
2857 case T_segment_width:
2859 m_board->m_LegacyDesignSettingsLoaded =
true;
2865 m_board->m_LegacyDesignSettingsLoaded =
true;
2869 case T_mod_edge_width:
2871 m_board->m_LegacyDesignSettingsLoaded =
true;
2875 case T_pcb_text_width:
2877 m_board->m_LegacyDesignSettingsLoaded =
true;
2881 case T_mod_text_width:
2883 m_board->m_LegacyDesignSettingsLoaded =
true;
2887 case T_pcb_text_size:
2890 m_board->m_LegacyDesignSettingsLoaded =
true;
2894 case T_mod_text_size:
2897 m_board->m_LegacyDesignSettingsLoaded =
true;
2903 m_board->m_LegacyDesignSettingsLoaded =
true;
2912 m_board->m_LegacyDesignSettingsLoaded =
true;
2921 m_board->m_LegacyDesignSettingsLoaded =
true;
2926 case T_pad_to_mask_clearance:
2931 case T_solder_mask_min_width:
2936 case T_pad_to_paste_clearance:
2941 case T_pad_to_paste_clearance_ratio:
2946 case T_allow_soldermask_bridges_in_footprints:
2989 case T_aux_axis_origin:
3013 case T_visible_elements:
3020 for(
size_t i = 0; i <
sizeof( int ) * CHAR_BIT; i++ )
3021 m_board->m_LegacyVisibleItems.set( i, visible & ( 1u << i ) );
3029 m_board->m_LegacyDesignSettingsLoaded =
true;
3033 case T_filled_areas_thickness:
3039 case T_pcbplotparams:
3045 parser.SyncLineReaderWith( *
this );
3047 plotParams.
Parse( &parser );
3048 SyncLineReaderWith( parser );
3050 m_board->SetPlotOptions( plotParams );
3055 m_board->GetDesignSettings().m_TentViasFront = tent;
3056 m_board->GetDesignSettings().m_TentViasBack = tent;
3061 case T_zone_defaults:
3066 Unexpected( CurText() );
3083 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
3085 if( token != T_LEFT )
3086 Expecting( T_LEFT );
3096 Unexpected( CurText() );
3103 std::map<PCB_LAYER_ID, ZONE_LAYER_PROPERTIES>& aProperties )
3108 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
3110 if( token != T_LEFT )
3111 Expecting( T_LEFT );
3121 case T_hatch_position:
3128 Unexpected( CurText() );
3133 aProperties.emplace( layer, properties );
3139 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
3141 if( token != T_LEFT )
3142 Expecting( T_LEFT );
3148 case T_edge_clearance:
3150 m_board->m_LegacyCopperEdgeClearanceLoaded =
true;
3154 case T_copper_line_width:
3159 case T_copper_text_dims:
3163 case T_courtyard_line_width:
3168 case T_edge_cuts_line_width:
3173 case T_silk_line_width:
3178 case T_silk_text_dims:
3182 case T_fab_layers_line_width:
3187 case T_fab_layers_text_dims:
3191 case T_other_layers_line_width:
3196 case T_other_layers_text_dims:
3200 case T_dimension_units:
3206 case T_dimension_precision:
3213 Unexpected( CurText() );
3221 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
3223 if( token == T_LEFT )
3243 case T_keep_upright:
3248 Expecting(
"size, thickness, italic or keep_upright" );
3256 wxCHECK_RET( CurTok() == T_net, wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net." ) );
3258 int netCode =
parseInt(
"net number" );
3260 NeedSYMBOLorNUMBER();
3261 wxString
name = FromUTF8();
3287 for(
T token = NextTok(); token != T_EOF; token = NextTok() )
3289 if( token == T_RIGHT )
3291 else if( token == T_LEFT )
3294 if( token != T_net_chain )
3301 std::vector<int> netCodes;
3302 std::vector<wxString> netNames;
3306 for(
T t = NextTok(); t != T_EOF; t = NextTok() )
3310 else if( t == T_LEFT )
3316 NeedSYMBOLorNUMBER();
3323 for(
T mt = NextTok(); mt != T_RIGHT; mt = NextTok() )
3333 if( tok == T_NUMBER )
3334 netCodes.push_back( (
int) strtol( CurText(),
nullptr, 10 ) );
3336 netNames.push_back( FromUTF8() );
3340 else if( mt == T_member )
3343 T inner = NextTok();
3345 if( inner == T_LEFT )
3348 if( inner == T_net )
3352 if( tok2 == T_NUMBER )
3353 netCodes.push_back( (
int) strtol( CurText(),
nullptr, 10 ) );
3355 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." ) );
3429 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( wxEmptyString );
3432 NeedSYMBOLorNUMBER();
3433 nc->SetName( FromUTF8() );
3435 nc->SetDescription( FromUTF8() );
3437 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
3439 if( token != T_LEFT )
3440 Expecting( T_LEFT );
3470 case T_diff_pair_width:
3474 case T_diff_pair_gap:
3480 NeedSYMBOLorNUMBER();
3482 wxString netName = FromUTF8();
3489 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment(
3490 netName, nc->GetName() );
3496 Expecting(
"clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, "
3497 "diff_pair_width, diff_pair_gap or add_net" );
3503 std::shared_ptr<NET_SETTINGS>& netSettings =
m_board->GetDesignSettings().m_NetSettings;
3505 if( netSettings->HasNetclass( nc->GetName() ) )
3509 THROW_IO_ERRORF(
_(
"Duplicate NETCLASS name '%s' in file '%s' at line %d, offset %d." ),
3510 nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(), CurOffset() );
3512 else if( nc->GetName() == netSettings->GetDefaultNetclass()->GetName() )
3514 netSettings->SetDefaultNetclass( nc );
3518 netSettings->SetNetclass( nc->GetName(), nc );
3525 wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve || CurTok() == T_fp_rect
3526 || CurTok() == T_fp_line || CurTok() == T_fp_poly || CurTok() == T_fp_ellipse
3527 || CurTok() == T_fp_ellipse_arc || CurTok() == T_gr_arc || CurTok() == T_gr_circle
3528 || CurTok() == T_gr_curve || CurTok() == T_gr_rect || CurTok() == T_gr_bbox
3529 || CurTok() == T_gr_line || CurTok() == T_gr_poly || CurTok() == T_gr_vector
3530 || CurTok() == T_gr_ellipse || CurTok() == T_gr_ellipse_arc,
3531 nullptr, wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_SHAPE." ) );
3536 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aParent );
3539 int ellipseMajor = 0;
3540 int ellipseMinor = 0;
3552 if( token == T_locked )
3554 shape->SetLocked(
true );
3558 if( token != T_LEFT )
3559 Expecting( T_LEFT );
3566 if( token != T_start )
3567 Expecting( T_start );
3571 shape->SetCenter( pt );
3577 if( token != T_end )
3582 shape->SetStart( pt );
3587 if( token != T_angle )
3588 Expecting( T_angle );
3595 VECTOR2I arc_start, arc_mid, arc_end;
3597 if( token != T_start )
3598 Expecting( T_start );
3606 if( token != T_mid )
3615 if( token != T_end )
3622 shape->SetArcGeometry( arc_start, arc_mid, arc_end );
3632 if( token == T_locked )
3634 shape->SetLocked(
true );
3638 if( token != T_LEFT )
3639 Expecting( T_LEFT );
3643 if( token != T_center )
3644 Expecting( T_center );
3648 shape->SetStart( pt );
3654 if( token != T_end )
3659 shape->SetEnd( pt );
3668 if( token == T_locked )
3670 shape->SetLocked(
true );
3674 if( token != T_LEFT )
3675 Expecting( T_LEFT );
3679 if( token != T_pts )
3683 shape->SetBezierC1(
parseXY());
3684 shape->SetBezierC2(
parseXY());
3688 shape->RebuildBezierToSegmentsPointsList(
m_board->GetDesignSettings().m_MaxError );
3690 shape->RebuildBezierToSegmentsPointsList(
ARC_HIGH_DEF );
3701 if( token == T_locked )
3703 shape->SetLocked(
true );
3707 if( token != T_LEFT )
3708 Expecting( T_LEFT );
3712 if( token != T_start )
3713 Expecting( T_start );
3717 shape->SetStart( pt );
3722 if( token != T_end )
3727 shape->SetEnd( pt );
3748 if( token == T_locked )
3750 shape->SetLocked(
true );
3754 if( token != T_LEFT )
3755 Expecting( T_LEFT );
3759 if( token != T_start )
3760 Expecting( T_start );
3764 shape->SetStart( pt );
3769 if( token != T_end )
3774 shape->SetEnd( pt );
3782 shape->SetPolyPoints( {} );
3788 if( token == T_locked )
3790 shape->SetLocked(
true );
3794 if( token != T_LEFT )
3795 Expecting( T_LEFT );
3799 if( token != T_pts )
3802 while( (token = NextTok() ) != T_RIGHT )
3811 case T_gr_ellipse_arc:
3817 Expecting(
"fp_arc, fp_circle, fp_curve, fp_ellipse, fp_ellipse_arc, "
3818 "fp_line, fp_poly or fp_rect" );
3822 Expecting(
"gr_arc, gr_circle, gr_curve, gr_ellipse, gr_ellipse_arc, "
3823 "gr_vector, gr_line, gr_poly, gr_rect or gr_bbox" );
3827 bool foundFill =
false;
3829 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3831 if( token != T_LEFT )
3832 Expecting( T_LEFT );
3852 case T_solder_mask_margin:
3853 shape->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
3870 strokeParser.SyncLineReaderWith( *
this );
3873 SyncLineReaderWith( strokeParser );
3887 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3889 if( token == T_LEFT )
3906 default: Expecting(
"yes, no, solid, none, hatch, reverse_hatch or cross_hatch" );
3932 case T_major_radius:
3937 case T_minor_radius:
3942 case T_rotation_angle:
3958 Expecting(
"layer, width, fill, tstamp, uuid, locked, net, status, "
3959 "solder_mask_margin, center, major_radius, minor_radius, "
3960 "rotation_angle, start_angle, or end_angle" );
3971 shape->SetFilled(
true );
3976 shape->SetFilled(
true );
3982 if( stroke.
GetWidth() <= 0 && !shape->IsAnyFill() )
3985 shape->SetStroke( stroke );
3987 if( shape->GetParentFootprint() )
3988 shape->SetLibStrokeWidth( stroke.
GetWidth() );
3992 shape->SetLibraryEllipse( ellipseCenter, ellipseMajor, ellipseMinor, ellipseRotation, ellipseStart,
3995 if( shape->GetParentFootprint() )
3996 shape->RebakeFromLib();
3998 else if( shape->GetParentFootprint() )
4000 const VECTOR2I libStart = shape->GetStart();
4001 const VECTOR2I libEnd = shape->GetEnd();
4004 shape->OverrideLibCoords( libStart, libEnd, libArcMid );
4007 shape->OverrideLibBezier( shape->GetBezierC1(), shape->GetBezierC2() );
4010 shape->OverrideLibPoly( shape->GetPolyShape() );
4012 shape->RebakeFromLib();
4015 return shape.release();
4021 wxCHECK_MSG( CurTok() == T_image,
nullptr,
4022 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a reference image." ) );
4024 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap = std::make_unique<PCB_REFERENCE_IMAGE>( aParent );
4026 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
4028 if( token != T_LEFT )
4029 Expecting( T_LEFT );
4040 bitmap->SetPosition( pos );
4069 data.reserve( 1 << 19 );
4071 while( token != T_RIGHT )
4073 if( !IsSymbol( token ) )
4074 Expecting(
"base64 image data" );
4080 wxMemoryBuffer buffer = wxBase64Decode( data );
4094 bitmap->SetLocked(
locked );
4107 Expecting(
"at, layer, scale, data, locked or uuid" );
4118 int legacyPPI =
image.GetLegacyPPI();
4120 if( legacyPPI > 0 &&
image.GetPPI() != legacyPPI )
4124 return bitmap.release();
4130 std::unique_ptr<PCB_TEXT>
text( aBaseText );
4132 wxCHECK_MSG( CurTok() == T_gr_text || CurTok() == T_fp_text,
nullptr,
4133 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXT." ) );
4137 T token = NextTok();
4139 if( !
text && parentFP )
4152 text = std::make_unique<PCB_TEXT>( parentFP );
4156 THROW_IO_ERRORF(
_(
"Cannot handle footprint text type %s" ), FromUTF8() );
4163 text = std::make_unique<PCB_TEXT>( aParent );
4167 if( token == T_locked )
4169 text->SetLocked(
true );
4173 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
4174 Expecting(
"text value" );
4176 wxString value = FromUTF8();
4177 value.Replace( wxT(
"%V" ), wxT(
"${VALUE}" ) );
4178 value.Replace( wxT(
"%R" ), wxT(
"${REFERENCE}" ) );
4179 text->SetText( value );
4197 text->SetVisible(
true );
4200 return text.release();
4207 bool hasAngle =
false;
4209 bool hasPos =
false;
4215 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
4217 if( token == T_LEFT )
4236 if( CurTok() == T_NUMBER )
4244 if( parentFP && CurTok() == T_unlocked )
4261 if( token == T_knockout )
4288 Expecting(
"layer, effects, locked, render_cache, uuid or tstamp" );
4304 Expecting(
"layer, effects, locked, render_cache or tstamp" );
4313 case T_render_cache:
4319 Expecting(
"layer, hide, effects, locked, render_cache or tstamp" );
4321 Expecting(
"layer, effects, locked, render_cache or tstamp" );
4356 wxCHECK_MSG( CurTok() == T_barcode,
nullptr,
4357 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_BARCODE." ) );
4359 std::unique_ptr<PCB_BARCODE> barcode = std::make_unique<PCB_BARCODE>( aParent );
4361 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
4363 if( token != T_LEFT )
4364 Expecting( T_LEFT );
4375 barcode->SetPosition( pos );
4378 if( CurTok() == T_NUMBER )
4394 barcode->SetWidth( w );
4395 barcode->SetHeight( h );
4401 if( NextTok() != T_STRING )
4402 Expecting( T_STRING );
4404 barcode->SetText( FromUTF8() );
4411 barcode->SetTextSize( h );
4419 std::string kind = CurText();
4420 if( kind ==
"code39" )
4422 else if( kind ==
"code128" )
4424 else if( kind ==
"datamatrix" || kind ==
"data_matrix" )
4426 else if( kind ==
"qr" || kind ==
"qrcode" )
4428 else if( kind ==
"microqr" || kind ==
"micro_qr" )
4431 Expecting(
"barcode type" );
4439 std::string ecc = CurText();
4440 if( ecc ==
"L" || ecc ==
"l" )
4442 else if( ecc ==
"M" || ecc ==
"m" )
4444 else if( ecc ==
"Q" || ecc ==
"q" )
4446 else if( ecc ==
"H" || ecc ==
"h" )
4449 Expecting(
"ecc level" );
4480 barcode->SetMargin(
VECTOR2I( marginX, marginY ) );
4486 Expecting(
"at, layer, size, text, text_height, type, ecc_level, locked, hide, knockout, margins or uuid" );
4490 barcode->AssembleBarcode();
4492 return barcode.release();
4513 aTextBox->EDA_TEXT::SetTextAngle( aTextBox->
GetTextAngle() );
4519 wxCHECK_MSG( CurTok() == T_gr_text_box || CurTok() == T_fp_text_box,
nullptr,
4520 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXTBOX." ) );
4522 std::unique_ptr<PCB_TEXTBOX> textbox = std::make_unique<PCB_TEXTBOX>( aParent );
4527 return textbox.release();
4533 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
4534 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
4536 std::unique_ptr<PCB_TABLECELL> cell = std::make_unique<PCB_TABLECELL>( aParent );
4541 return cell.release();
4552 bool foundMargins =
false;
4554 T token = NextTok();
4557 if( token == T_locked )
4563 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
4564 Expecting(
"text value" );
4566 aTextBox->
SetText( FromUTF8() );
4568 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4570 if( token != T_LEFT )
4571 Expecting( T_LEFT );
4591 if( token != T_end )
4606 while( (token = NextTok() ) != T_RIGHT )
4621 strokeParser.SyncLineReaderWith( *
this );
4624 SyncLineReaderWith( strokeParser );
4639 foundMargins =
true;
4656 cell->SetColSpan(
parseInt(
"column span" ) );
4657 cell->SetRowSpan(
parseInt(
"row span" ) );
4661 Expecting(
"locked, start, pts, angle, width, stroke, border, margins, knockout, "
4662 "layer, effects, render_cache, uuid or tstamp" );
4679 case T_render_cache:
4686 Expecting(
"locked, start, pts, angle, width, margins, knockout, layer, effects, "
4687 "span, render_cache, uuid or tstamp" );
4691 Expecting(
"locked, start, pts, angle, width, stroke, border, margins, knockout,"
4692 "layer, effects, render_cache, uuid or tstamp" );
4715 wxCHECK_MSG( CurTok() == T_table,
nullptr,
4716 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
4720 std::unique_ptr<PCB_TABLE>
table = std::make_unique<PCB_TABLE>( aParent, -1 );
4722 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
4724 if( token != T_LEFT )
4725 Expecting( T_LEFT );
4731 case T_column_count:
4756 case T_column_widths:
4760 while( ( token = NextTok() ) != T_RIGHT )
4770 while( ( token = NextTok() ) != T_RIGHT )
4777 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4779 if( token != T_LEFT )
4780 Expecting( T_LEFT );
4784 if( token != T_table_cell )
4785 Expecting(
"table_cell" );
4793 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4795 if( token != T_LEFT )
4796 Expecting( T_LEFT );
4815 strokeParser.SyncLineReaderWith( *
this );
4818 SyncLineReaderWith( strokeParser );
4820 table->SetBorderStroke( borderStroke );
4825 Expecting(
"external, header or stroke" );
4833 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4835 if( token != T_LEFT )
4836 Expecting( T_LEFT );
4855 strokeParser.SyncLineReaderWith( *
this );
4858 SyncLineReaderWith( strokeParser );
4860 table->SetSeparatorsStroke( separatorsStroke );
4865 Expecting(
"rows, cols, or stroke" );
4873 Expecting(
"columns, layer, col_widths, row_heights, border, separators, header or cells" );
4877 return table.release();
4883 wxCHECK_MSG( CurTok() == T_dimension,
nullptr,
4884 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as DIMENSION." ) );
4888 std::unique_ptr<PCB_DIMENSION_BASE> dim;
4893 if( token == T_locked )
4900 if( token != T_LEFT )
4905 bool isLegacyDimension =
false;
4906 bool isStyleKnown =
false;
4909 if( token == T_width )
4911 isLegacyDimension =
true;
4912 dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
4918 if( token != T_type )
4919 Expecting( T_type );
4923 case T_aligned: dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
break;
4924 case T_orthogonal: dim = std::make_unique<PCB_DIM_ORTHOGONAL>( aParent );
break;
4925 case T_leader: dim = std::make_unique<PCB_DIM_LEADER>( aParent );
break;
4926 case T_center: dim = std::make_unique<PCB_DIM_CENTER>( aParent );
break;
4927 case T_radial: dim = std::make_unique<PCB_DIM_RADIAL>( aParent );
break;
4928 default: wxFAIL_MSG( wxT(
"Cannot parse unknown dimension type " )
4929 + GetTokenString( CurTok() ) );
4939 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4941 if( token != T_LEFT )
4942 Expecting( T_LEFT );
4967 bool is_aligned = dim->GetKeepTextAligned();
4973 dim->SetKeepTextAligned(
false );
4978 if( isLegacyDimension )
4983 dim->SetAutoUnits(
true );
4985 dim->SetUnits( units );
4990 dim->SetKeepTextAligned( is_aligned );
4991 dim->SetTextPositionMode( t_dim_pos );
5002 dim->SetStart( point );
5004 dim->SetEnd( point );
5024 case T_leader_length:
5040 int orientation =
parseInt(
"orthogonal dimension orientation" );
5046 orientation = std::clamp( orientation, 0, 1 );
5055 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5063 NeedSYMBOLorNUMBER();
5064 dim->SetPrefix( FromUTF8() );
5069 NeedSYMBOLorNUMBER();
5070 dim->SetSuffix( FromUTF8() );
5076 int mode =
parseInt(
"dimension units mode" );
5077 mode = std::max( 0, std::min( 4, mode ) );
5083 case T_units_format:
5085 int format =
parseInt(
"dimension units format" );
5086 format = std::clamp( format, 0, 3 );
5097 case T_override_value:
5098 NeedSYMBOLorNUMBER();
5099 dim->SetOverrideTextEnabled(
true );
5100 dim->SetOverrideText( FromUTF8() );
5104 case T_suppress_zeroes:
5109 std::cerr <<
"Unknown format token: " << GetTokenString( token ) << std::endl;
5110 Expecting(
"prefix, suffix, units, units_format, precision, override_value, "
5111 "suppress_zeroes" );
5119 isStyleKnown =
true;
5122 dim->SetKeepTextAligned(
false );
5124 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5132 dim->SetLineThickness(
parseBoardUnits(
"extension line thickness value" ) );
5136 case T_arrow_direction:
5139 if( token == T_inward )
5141 else if( token == T_outward )
5144 Expecting(
"inward or outward" );
5149 case T_arrow_length:
5155 case T_text_position_mode:
5157 int mode =
parseInt(
"text position mode" );
5158 mode = std::max( 0, std::min( 3, mode ) );
5164 case T_extension_height:
5167 wxCHECK_MSG( aligned,
nullptr, wxT(
"Invalid extension_height token" ) );
5173 case T_extension_offset:
5174 dim->SetExtensionOffset(
parseBoardUnits(
"extension offset value" ) );
5178 case T_keep_text_aligned:
5184 wxCHECK_MSG( dim->Type() ==
PCB_DIM_LEADER_T,
nullptr, wxT(
"Invalid text_frame token" ) );
5188 int textFrame =
parseInt(
"text frame mode" );
5189 textFrame = std::clamp( textFrame, 0, 3 );
5196 Expecting(
"thickness, arrow_length, arrow_direction, text_position_mode, "
5197 "extension_height, extension_offset" );
5210 if( token != T_pts )
5216 dim->SetStart( point );
5230 if( token != T_pts )
5236 dim->SetEnd( point );
5250 if( token == T_pts )
5272 if( token != T_pts )
5286 if( token != T_pts )
5300 if( token != T_pts )
5314 if( token != T_pts )
5328 dim->SetLocked( isLocked );
5333 Expecting(
"layer, tstamp, uuid, gr_text, feature1, feature2, crossbar, arrow1a, "
5334 "arrow1b, arrow2a, or arrow2b" );
5339 dim->SetLocked(
true );
5343 return dim.release();
5365 wxCHECK_MSG( CurTok() == T_module || CurTok() == T_footprint,
nullptr,
5366 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FOOTPRINT." ) );
5373 double parsedScaleX = 1.0;
5374 double parsedScaleY = 1.0;
5376 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
5378 footprint->SetInitialComments( aInitialComments );
5381 footprint->SetStaticComponentClass(
m_board->GetComponentClassManager().GetNoneComponentClass() );
5385 if( !IsSymbol( token ) && token != T_NUMBER )
5386 Expecting(
"symbol|number" );
5392 THROW_IO_ERRORF(
_(
"Invalid footprint ID in\nfile: %s\nline: %d\noffset: %d." ),
5393 CurSource(), CurLineNumber(), CurOffset() );
5403 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5405 if( token == T_LEFT )
5415 int this_version =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
5420 footprint->SetFileFormatVersionAtLoad( this_version );
5431 case T_generator_version:
5480 footprint->SetPosition( pt );
5483 if( token == T_NUMBER )
5488 else if( token != T_RIGHT )
5490 Expecting( T_RIGHT );
5500 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5502 if( token != T_LEFT )
5503 Expecting( T_LEFT );
5526 if( !std::isfinite( parsedScaleX ) || parsedScaleX <= 0.0 )
5529 if( !std::isfinite( parsedScaleY ) || parsedScaleY <= 0.0 )
5536 Expecting(
"translate, rotate, or scale" );
5540 footprint->SetPosition( trsTranslate );
5541 footprint->SetOrientation( trsRotate );
5542 footprint->SetTransformScale( parsedScaleX, parsedScaleY );
5547 NeedSYMBOLorNUMBER();
5548 footprint->SetLibDescription( FromUTF8() );
5553 NeedSYMBOLorNUMBER();
5554 footprint->SetKeywords( FromUTF8() );
5561 wxString pName = FromUTF8();
5563 wxString pValue = FromUTF8();
5571 if( pName ==
"ki_keywords" || pName ==
"ki_locked" )
5579 if( pName ==
"ki_description" )
5587 if( pName ==
"Sheetfile" || pName ==
"Sheet file" )
5589 footprint->SetSheetfile( pValue );
5594 if( pName ==
"Sheetname" || pName ==
"Sheet name" )
5596 footprint->SetSheetname( pValue );
5603 std::unique_ptr<PCB_FIELD> unusedField;
5607 if( pName ==
"ki_fp_filters" )
5609 footprint->SetFilters( pValue );
5614 unusedField = std::make_unique<PCB_FIELD>( footprint.get(),
FIELD_T::USER );
5615 field = unusedField.get();
5617 else if( pName ==
"Footprint" )
5623 field = unusedField.get();
5625 else if( footprint->HasField( pName ) )
5627 field = footprint->GetField( pName );
5633 footprint->Add( field );
5654 NeedSYMBOLorNUMBER();
5655 footprint->SetPath(
KIID_PATH( FromUTF8() ) );
5661 footprint->SetSheetname( FromUTF8() );
5667 footprint->SetSheetfile( FromUTF8() );
5673 std::vector<FOOTPRINT::FP_UNIT_INFO> unitInfos;
5676 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5678 if( token == T_LEFT )
5681 if( token == T_unit )
5685 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5687 if( token == T_LEFT )
5690 if( token == T_name )
5692 NeedSYMBOLorNUMBER();
5693 info.m_unitName = FromUTF8();
5696 else if( token == T_pins )
5699 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5701 if( token == T_STRING || token == T_NUMBER )
5703 info.m_pins.emplace_back( FromUTF8() );
5707 Expecting(
"pin number" );
5718 unitInfos.push_back(
info );
5727 if( !unitInfos.empty() )
5728 footprint->SetUnitInfo( unitInfos );
5733 case T_autoplace_cost90:
5734 case T_autoplace_cost180:
5735 parseInt(
"legacy auto-place cost" );
5739 case T_private_layers:
5743 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5748 privateLayers.
set( it->second );
5750 Expecting(
"layer name" );
5759 footprint->SetPrivateLayers( privateLayers );
5763 case T_net_tie_pad_groups:
5764 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5765 footprint->AddNetTiePadGroup( CurStr() );
5769 case T_duplicate_pad_numbers_are_jumpers:
5770 footprint->SetDuplicatePadNumbersAreJumpers(
parseBool() );
5774 case T_jumper_pad_groups:
5777 std::vector<std::set<wxString>>& groups = footprint->JumperPadGroups();
5778 std::set<wxString>* currentGroup =
nullptr;
5780 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
5782 switch(
static_cast<int>( token ) )
5785 currentGroup = &groups.emplace_back();
5790 currentGroup->insert( FromUTF8() );
5795 currentGroup =
nullptr;
5799 Expecting(
"list of pad names" );
5806 case T_solder_mask_margin:
5807 footprint->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
5812 footprint->SetLocalSolderMaskMargin( {} );
5816 case T_solder_paste_margin:
5817 footprint->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
5822 footprint->SetLocalSolderPasteMargin( {} );
5826 case T_solder_paste_ratio:
5827 case T_solder_paste_margin_ratio:
5828 footprint->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
5833 footprint->SetLocalSolderPasteMarginRatio( {} );
5838 footprint->SetLocalClearance(
parseBoardUnits(
"local clearance value" ) );
5843 footprint->SetLocalClearance( {} );
5847 case T_zone_connect:
5852 case T_thermal_width:
5860 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5868 case T_through_hole:
5880 case T_exclude_from_pos_files:
5884 case T_exclude_from_bom:
5888 case T_allow_missing_courtyard:
5889 footprint->SetAllowMissingCourtyard(
true );
5896 case T_allow_soldermask_bridges:
5897 footprint->SetAllowSolderMaskBridges(
true );
5901 Expecting(
"through_hole, smd, virtual, board_only, exclude_from_pos_files, "
5902 "exclude_from_bom or allow_solder_mask_bridges" );
5905 footprint->SetAttributes( attributes );
5914 switch( field->GetId() )
5918 footprint->Reference().SetUuidDirect(
text->m_Uuid );
5924 footprint->Value().SetUuidDirect(
text->m_Uuid );
5965 case T_fp_ellipse_arc:
6003 if( token == T_LEFT )
6008 if( token != T_type )
6009 Expecting( T_type );
6013 if( CurTok() == T_extruded )
6019 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6021 if( token != T_LEFT )
6022 Expecting( T_LEFT );
6035 case T_overall_height:
6040 case T_body_pcb_gap:
6048 wxString layerName =
From_UTF8( CurText() );
6050 if( layerName == wxT(
"auto" ) )
6054 else if( layerName == wxT(
"pad_bbox" ) )
6073 wxString matName =
From_UTF8( CurText() );
6075 if( matName == wxT(
"matte" ) )
6077 else if( matName == wxT(
"metal" ) )
6079 else if( matName == wxT(
"copper" ) )
6090 NeedSYMBOLorNUMBER();
6091 wxString first =
From_UTF8( CurText() );
6093 if( first == wxT(
"unspecified" ) )
6113 if( token != T_xyz )
6127 if( token != T_xyz )
6141 if( token != T_xyz )
6152 Expecting(
"hide, overall_height, body_pcb_gap, layer, material, "
6153 "color, offset, scale, or rotate" );
6159 Expecting(
"extruded" );
6166 footprint->Add3DModel(
model );
6215 case T_embedded_fonts:
6217 footprint->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
6222 case T_embedded_files:
6225 embeddedFilesParser.SyncLineReaderWith( *
this );
6229 embeddedFilesParser.
ParseEmbedded( footprint->GetEmbeddedFiles() );
6237 for(
int tok = embeddedFilesParser.NextTok(); tok !=
DSN_EOF; tok = embeddedFilesParser.NextTok() )
6241 else if( tok ==
DSN_RIGHT && --depth < 0 )
6246 SyncLineReaderWith( embeddedFilesParser );
6250 case T_component_classes:
6252 std::unordered_set<wxString> componentClassNames;
6254 while( ( token = NextTok() ) != T_RIGHT )
6256 if( token != T_LEFT )
6257 Expecting( T_LEFT );
6259 if( ( token = NextTok() ) != T_class )
6260 Expecting( T_class );
6262 NeedSYMBOLorNUMBER();
6263 componentClassNames.insert(
From_UTF8( CurText() ) );
6267 footprint->SetTransientComponentClassNames( componentClassNames );
6270 footprint->ResolveComponentClassNames(
m_board, componentClassNames );
6280 Expecting(
"at, descr, locked, placed, tedit, tstamp, uuid, variant, "
6281 "autoplace_cost90, autoplace_cost180, attr, clearance, "
6282 "embedded_files, fp_arc, fp_circle, fp_curve, fp_line, fp_poly, "
6283 "fp_rect, fp_text, pad, group, generator, model, path, solder_mask_margin, "
6284 "solder_paste_margin, solder_paste_margin_ratio, tags, thermal_gap, "
6285 "version, zone, zone_connect, or component_classes" );
6289 footprint->FixUpPadsForBoard(
m_board );
6301 if( footprint->GetKeywords().StartsWith( wxT(
"net tie" ) ) )
6305 for(
PAD*
pad : footprint->Pads() )
6307 if( !padGroup.IsEmpty() )
6308 padGroup += wxS(
", " );
6310 padGroup +=
pad->GetNumber();
6313 if( !padGroup.IsEmpty() )
6314 footprint->AddNetTiePadGroup( padGroup );
6318 footprint->SetAttributes( attributes );
6320 footprint->SetFPID( fpid );
6322 return footprint.release();
6328 wxCHECK_RET( CurTok() == T_stackup,
"Expected stackup token" );
6334 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
6336 if( CurTok() != T_LEFT )
6337 Expecting( T_LEFT );
6345 NeedSYMBOLorNUMBER();
6350 Expecting(
"layer name" );
6352 layers.
set( it->second );
6358 Expecting(
"layer" );
6366 if( gotCuLayers.count() % 2 != 0 )
6368 THROW_IO_ERRORF(
_(
"Invalid stackup in footprint: odd number of copper layers (%d)." ),
6369 gotCuLayers.count() );
6373 if( gotCuLayers != expectedCuLayers )
6375 THROW_IO_ERROR(
_(
"Invalid stackup in footprint: copper layers are not contiguous." ) );
6380 THROW_IO_ERROR(
_(
"Invalid stackup in footprint: technology layers are implicit in footprints and "
6381 "should not be specified in the stackup." ) );
6392 wxCHECK_MSG( CurTok() == T_pad,
nullptr, wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PAD." ) );
6396 bool foundNet =
false;
6397 bool foundNetcode =
false;
6399 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
6401 NeedSYMBOLorNUMBER();
6402 pad->SetNumber( FromUTF8() );
6404 T token = NextTok();
6433 case T_np_thru_hole:
6438 Expecting(
"thru_hole, smd, connect, or np_thru_hole" );
6472 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
6475 std::optional<EDA_ANGLE> thermalBrAngleOverride;
6477 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6479 if( token == T_locked )
6485 if( token != T_LEFT )
6486 Expecting( T_LEFT );
6502 pad->SetFPRelativePosition( pt );
6508 if( token == T_NUMBER )
6513 else if( token == T_RIGHT )
6519 Expecting(
") or angle value" );
6536 bool haveWidth =
false;
6539 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6541 if( token == T_LEFT )
6555 drillSize.
y = drillSize.
x;
6574 Expecting(
"oval, size, or offset" );
6583 pad->SetLibDrillSize( drillSize );
6595 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6597 if( token != T_LEFT )
6598 Expecting( T_LEFT );
6623 Expecting(
"size or layers" );
6630 case T_tertiary_drill:
6635 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6637 if( token != T_LEFT )
6638 Expecting( T_LEFT );
6663 Expecting(
"size or layers" );
6674 pad->SetLayerSet( layerMask );
6690 CurSource(), CurLineNumber(), CurOffset() );
6694 foundNetcode =
true;
6700 if( !IsSymbol( token ) )
6702 Expecting(
"net name" );
6708 wxString netName( FromUTF8() );
6717 if( netName !=
m_board->FindNet(
pad->GetNetCode() )->GetNetname() )
6721 _(
"Net name doesn't match ID in\nfile: %s\nline: %d offset: %d" ),
6722 CurSource(), CurLineNumber(), CurOffset() );
6735 pad->SetNet( netinfo );
6743 NeedSYMBOLorNUMBER();
6744 pad->SetPinFunction( FromUTF8() );
6749 NeedSYMBOLorNUMBER();
6750 pad->SetPinType( FromUTF8() );
6754 case T_sim_electrical_type:
6762 default: Expecting(
"sink or source" );
6783 case T_solder_mask_margin:
6784 pad->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6789 pad->SetLocalSolderMaskMargin( {} );
6793 case T_solder_paste_margin:
6794 pad->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
6799 pad->SetLocalSolderPasteMargin( {} );
6803 case T_solder_paste_margin_ratio:
6804 pad->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
6809 pad->SetLocalSolderPasteMarginRatio( {} );
6819 pad->SetLocalClearance( {} );
6827 case T_zone_connect:
6832 case T_thermal_width:
6833 case T_thermal_bridge_width:
6838 case T_thermal_bridge_angle:
6849 case T_roundrect_rratio:
6854 case T_chamfer_ratio:
6866 bool end_list =
false;
6886 case T_bottom_right:
6896 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or chamfer_bottom_right" );
6907 while( token != T_RIGHT )
6922 case T_RIGHT:
break;
6926 Expecting(
"pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc"
6927 " pad_prop_heatsink or pad_prop_castellated" );
6944 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6946 if( token == T_LEFT )
6977 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
6984 case T_remove_unused_layers:
6987 pad->SetRemoveUnconnected( remove );
6991 case T_keep_end_layers:
6994 pad->SetKeepTopBottom( keep );
7001 pad->Padstack().FrontOuterLayers().has_solder_mask = front;
7002 pad->Padstack().BackOuterLayers().has_solder_mask = back;
7006 case T_zone_layer_connections:
7013 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7018 Expecting(
"copper layer name" );
7039 case T_front_post_machining:
7043 case T_back_post_machining:
7048 Expecting(
"at, locked, drill, layers, net, die_length, roundrect_rratio, "
7049 "solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, uuid, "
7050 "clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
7051 "pinfunction, pintype, zone_connect, thermal_width, thermal_gap, padstack, "
7052 "teardrops, front_post_machining, or back_post_machining" );
7059 pad->SetNetCode( 0,
true );
7062 if( thermalBrAngleOverride )
7064 pad->SetThermalSpokeAngle( *thermalBrAngleOverride );
7087 if( !
pad->CanHaveNumber() )
7091 pad->SetNumber( wxEmptyString );
7095 if(
pad->GetSizeX() <= 0 ||
pad->GetSizeY() <= 0 )
7100 wxString::Format(
_(
"Invalid zero-sized pad pinned to %s in\nfile: %s\nline: %d\noffset: %d" ),
7101 wxT(
"1µm" ), CurSource(), CurLineNumber(), CurOffset() ) );
7104 return pad.release();
7111 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
7113 if( token != T_LEFT )
7114 Expecting( T_LEFT );
7129 default: Expecting(
"circle or rect" );
7144 default: Expecting(
"outline or convexhull" );
7151 Expecting(
"anchor or clearance" );
7165 T token = NextTok();
7171 default: Expecting(
"counterbore or countersink" );
7175 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7177 if( token != T_LEFT )
7178 Expecting( T_LEFT );
7200 Expecting(
"size, depth, or angle" );
7210 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
7212 if( token != T_LEFT )
7213 Expecting( T_LEFT );
7224 case T_front_inner_back:
7233 Expecting(
"front_inner_back or custom" );
7244 if( curText ==
"Inner" )
7248 THROW_IO_ERRORF(
_(
"Invalid padstack layer in\nfile: %s\nline: %d\noffset: %d." ),
7249 CurSource(), CurLineNumber(), CurOffset() );
7261 THROW_IO_ERRORF(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
7262 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
7269 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7271 if( token != T_LEFT )
7272 Expecting( T_LEFT );
7310 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
7346 case T_roundrect_rratio:
7351 case T_chamfer_ratio:
7366 bool end_list =
false;
7386 case T_bottom_right:
7396 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
7397 "chamfer_bottom_right" );
7407 case T_thermal_bridge_width:
7417 case T_thermal_bridge_angle:
7422 case T_zone_connect:
7424 magic_enum::enum_cast<ZONE_CONNECTION>(
parseInt(
"zone connection value" ) );
7444 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7446 if( token != T_LEFT )
7447 Expecting( T_LEFT );
7486 while( ( token = NextTok() ) != T_RIGHT )
7499 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7501 if( token == T_LEFT )
7532 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
7549 Expecting(
"mode or layer" );
7558 while( NextTok() != T_RIGHT )
7563 KIID uuid( CurStr() );
7571 wxCHECK_RET( CurTok() == T_group, wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
7577 groupInfo.
parent = aParent;
7579 while( ( token = NextTok() ) != T_LEFT )
7581 if( token == T_STRING )
7582 groupInfo.
name = FromUTF8();
7583 else if( token == T_locked )
7586 Expecting(
"group name or locked" );
7589 for( ; token != T_RIGHT; token = NextTok() )
7591 if( token != T_LEFT )
7592 Expecting( T_LEFT );
7610 if( !IsSymbol( token ) && token != T_NUMBER )
7611 Expecting(
"symbol|number" );
7613 wxString
name = FromUTF8();
7617 name.Replace(
"{slash}",
"/" );
7623 if(
static_cast<int>(
name.size() ) > bad_pos )
7625 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
7632 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
7649 Expecting(
"uuid, locked, lib_id, or members" );
7657 wxCHECK_RET( CurTok() == T_constraint,
7658 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_CONSTRAINT." ) );
7662 info.parent = aParent;
7664 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
7666 if( token != T_LEFT )
7667 Expecting( T_LEFT );
7686 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7688 if( token != T_LEFT )
7689 Expecting( T_LEFT );
7691 if( NextTok() != T_member )
7692 Expecting(
"member" );
7695 KIID memberId( CurStr() );
7708 if( token != T_RIGHT )
7710 if( token != T_NUMBER )
7711 Expecting(
"vertex index" );
7739 Expecting(
"type, uuid, members, value, or driving" );
7755 BOARD* board =
dynamic_cast<BOARD*
>( aParent );
7758 std::unordered_map<KIID, BOARD_ITEM*> fpItemMap;
7765 fpItemMap.insert( { child->
m_Uuid, child } );
7776 auto it = cache.find( aId );
7778 return it != cache.end() ? it->second :
nullptr;
7780 else if( footprint )
7782 auto it = fpItemMap.find( aId );
7784 return it != fpItemMap.end() ? it->second :
nullptr;
7792 std::unique_ptr<PCB_CONSTRAINT> constraint =
7793 std::make_unique<PCB_CONSTRAINT>(
info.parent,
info.type );
7795 constraint->SetUuidDirect(
info.uuid );
7796 constraint->SetValue(
info.value );
7797 constraint->SetDriving(
info.driving );
7811 resolvedId = remap->second;
7842 wxCHECK_RET( CurTok() == T_generated,
7843 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GENERATOR." ) );
7851 genInfo.
parent = aParent;
7858 if( token != T_uuid && token != T_id )
7859 Expecting( T_uuid );
7865 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7867 if( token != T_LEFT )
7868 Expecting( T_LEFT );
7882 genInfo.
name = FromUTF8();
7888 genInfo.
locked = token == T_yes;
7903 wxString pName = FromUTF8();
7909 genInfo.
properties.emplace( pName, wxAny(
true ) );
7914 genInfo.
properties.emplace( pName, wxAny(
false ) );
7921 genInfo.
properties.emplace( pName, wxAny( pValue ) );
7928 wxString pValue = FromUTF8();
7948 genInfo.
properties.emplace( pName, wxAny( pt ) );
7958 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7967 Expecting(
"xy or pts" );
7974 Expecting(
"a number, symbol, string or (" );
7990 wxCHECK_MSG( CurTok() == T_arc,
nullptr, wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ARC." ) );
7993 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board );
7995 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
7998 if( token == T_locked )
8000 arc->SetLocked(
true );
8004 if( token != T_LEFT )
8005 Expecting( T_LEFT );
8014 arc->SetStart( pt );
8046 case T_solder_mask_margin:
8047 arc->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
8073 Expecting(
"start, mid, end, width, layer, solder_mask_margin, net, tstamp, uuid or status" );
8083 return arc.release();
8089 wxCHECK_MSG( CurTok() == T_segment,
nullptr,
8090 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TRACK." ) );
8093 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
8095 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
8098 if( token == T_locked )
8100 track->SetLocked(
true );
8104 if( token != T_LEFT )
8105 Expecting( T_LEFT );
8114 track->SetStart( pt );
8121 track->SetEnd( pt );
8139 case T_solder_mask_margin:
8140 track->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
8166 Expecting(
"start, end, width, layer, solder_mask_margin, net, tstamp, uuid or locked" );
8176 return track.release();
8182 wxCHECK_MSG( CurTok() == T_via,
nullptr,
8183 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_VIA." ) );
8186 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
8195 via->Padstack().FrontOuterLayers().has_covering =
false;
8196 via->Padstack().BackOuterLayers().has_covering =
false;
8197 via->Padstack().FrontOuterLayers().has_plugging =
false;
8198 via->Padstack().BackOuterLayers().has_plugging =
false;
8199 via->Padstack().Drill().is_filled =
false;
8200 via->Padstack().Drill().is_capped =
false;
8203 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
8206 if( token == T_locked )
8208 via->SetLocked(
true );
8212 if( token == T_LEFT )
8232 via->SetStart( pt );
8254 via->SetLayerPair( layer1, layer2 );
8257 Expecting(
"layer name" );
8267 case T_remove_unused_layers:
8269 via->SetRemoveUnconnected(
true );
8273 case T_keep_end_layers:
8275 via->SetKeepStartEnd(
true );
8279 case T_start_end_only:
8285 case T_zone_layer_connections:
8293 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8298 Expecting(
"copper layer name" );
8317 via->Padstack().FrontOuterLayers().has_solder_mask = front;
8318 via->Padstack().BackOuterLayers().has_solder_mask = back;
8325 via->Padstack().FrontOuterLayers().has_covering = front;
8326 via->Padstack().BackOuterLayers().has_covering = back;
8333 via->Padstack().FrontOuterLayers().has_plugging = front;
8334 via->Padstack().BackOuterLayers().has_plugging = back;
8374 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8376 if( token != T_LEFT )
8377 Expecting( T_LEFT );
8402 Expecting(
"size or layers" );
8409 case T_tertiary_drill:
8414 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8416 if( token != T_LEFT )
8417 Expecting( T_LEFT );
8442 Expecting(
"size or layers" );
8449 case T_front_post_machining:
8453 case T_back_post_machining:
8458 Expecting(
"blind, micro, at, size, drill, layers, net, free, tstamp, uuid, status, "
8459 "teardrops, backdrill, tertiary_drill, front_post_machining, or back_post_machining" );
8463 return via.release();
8467std::pair<std::optional<bool>, std::optional<bool>>
8470 T token = NextTok();
8472 std::optional<bool> front{};
8473 std::optional<bool> back{};
8475 if( token != T_LEFT && aAllowLegacyFormat )
8478 while( token != T_RIGHT )
8480 if( token == T_front )
8484 else if( token == T_back )
8488 else if( token == T_none )
8495 Expecting(
"front, back or none" );
8503#if defined( __GNUC__ ) && !defined( __clang__ )
8504#pragma GCC diagnostic push
8505#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
8507 return { front, back };
8508#if defined( __GNUC__ ) && !defined( __clang__ )
8509#pragma GCC diagnostic pop
8513 while( token != T_RIGHT )
8515 if( token != T_LEFT )
8520 if( token == T_front )
8522 else if( token == T_back )
8525 Expecting(
"front or back" );
8532 return { front, back };
8540 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
8542 if( token != T_LEFT )
8543 Expecting( T_LEFT );
8556 default: Expecting(
"front_inner_back or custom" );
8567 if( curText ==
"Inner" )
8571 THROW_IO_ERRORF(
_(
"Invalid padstack layer in\nfile: %s\nline: %d\noffset: %d." ),
8572 CurSource(), CurLineNumber(), CurOffset() );
8584 THROW_IO_ERRORF(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
8585 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
8588 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8590 if( token != T_LEFT )
8591 Expecting( T_LEFT );
8601 padstack.
SetSize( { diameter, diameter }, curLayer );
8608 Expecting(
"size" );
8616 Expecting(
"mode or layer" );
8625 wxCHECK_MSG( CurTok() == T_zone,
nullptr,
8626 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ZONE." ) );
8632 wxString legacyNetnameFromFile;
8635 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
8636 std::map<PCB_LAYER_ID, std::vector<SEG>> legacySegs;
8638 bool addedFilledPolygons =
false;
8644 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aParent );
8646 zone->SetAssignedPriority( 0 );
8657 zone->SetCornerRadius( 0 );
8658 zone->SetHatchSmoothingLevel( 0 );
8659 zone->SetLocked(
false );
8661 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
8664 if( token == T_locked )
8666 zone->SetLocked(
true );
8670 if( token == T_LEFT )
8680 NeedSYMBOLorNUMBER();
8681 legacyNetnameFromFile = FromUTF8();
8708 if( token != T_none && token != T_edge && token != T_full )
8709 Expecting(
"none, edge, or full" );
8724 zone->SetAssignedPriority(
parseInt(
"zone priority" ) );
8728 case T_connect_pads:
8729 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8731 if( token == T_LEFT )
8744 case T_thru_hole_only:
8754 Expecting(
"yes, no, or clearance" );
8760 case T_min_thickness:
8765 case T_filled_areas_thickness:
8772 isStrokedFill =
false;
8778 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8780 if( token == T_LEFT )
8786 zone->SetIsFilled(
true );
8792 if( token != T_segment && token != T_hatch && token != T_polygon
8793 && token != T_thieving )
8795 Expecting(
"segment, hatch, polygon or thieving" );
8807 Expecting(
"segment, hatch or polygon "
8808 "(thieving requires file version >= 20260513)" );
8824 case T_hatch_thickness:
8834 case T_hatch_orientation:
8837 zone->SetHatchOrientation( orientation );
8842 case T_hatch_smoothing_level:
8843 zone->SetHatchSmoothingLevel(
parseDouble( T_hatch_smoothing_level ) );
8847 case T_hatch_smoothing_value:
8848 zone->SetHatchSmoothingValue(
parseDouble( T_hatch_smoothing_value ) );
8852 case T_hatch_border_algorithm:
8855 if( token != T_hatch_thickness && token != T_min_thickness )
8856 Expecting(
"hatch_thickness or min_thickness" );
8858 zone->SetHatchBorderAlgorithm( token == T_hatch_thickness ? 1 : 0 );
8862 case T_hatch_min_hole_area:
8863 zone->SetHatchHoleMinArea(
parseDouble( T_hatch_min_hole_area ) );
8871 Expecting(
"thieving requires file version >= 20260513" );
8876 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8878 if( token == T_LEFT )
8891 default: Expecting(
"dots, squares or hatch" );
8946 Expecting(
"type, size, gap, width, stagger or orientation" );
8950 zone->SetThievingSettings( thieving );
8954 case T_arc_segments:
8964 case T_thermal_bridge_width:
8965 zone->SetThermalReliefSpokeWidth(
parseBoardUnits( T_thermal_bridge_width ) );
8977 if( !zone->GetIsRuleArea() )
8983 if( !zone->GetIsRuleArea() )
8989 Expecting(
"none, chamfer, or fillet" );
8998 if( !zone->GetIsRuleArea() )
8999 zone->SetCornerRadius( tmp );
9004 case T_island_removal_mode:
9005 tmp =
parseInt(
"island_removal_mode" );
9007 if( tmp >= 0 && tmp <= 2 )
9013 case T_island_area_min:
9016 zone->SetMinIslandArea( area *
pcbIUScale.IU_PER_MM );
9022 Expecting(
"mode, arc_segments, thermal_gap, thermal_bridge_width, "
9023 "hatch_thickness, hatch_gap, hatch_orientation, "
9024 "hatch_smoothing_level, hatch_smoothing_value, "
9025 "hatch_border_algorithm, hatch_min_hole_area, thieving, "
9026 "smoothing, radius, island_removal_mode, or island_area_min" );
9033 zone->SetIsRuleArea(
true );
9035 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9037 if( token == T_LEFT )
9046 zone->SetPlacementAreaSource( FromUTF8() );
9049 case T_component_class:
9053 zone->SetPlacementAreaSource( FromUTF8() );
9060 zone->SetPlacementAreaSource( FromUTF8() );
9067 if( token == T_yes )
9068 zone->SetPlacementAreaEnabled(
true );
9069 else if( token == T_no )
9070 zone->SetPlacementAreaEnabled(
false );
9072 Expecting(
"yes or no" );
9078 Expecting(
"enabled, sheetname, component_class, or group" );
9090 zone->SetIsRuleArea(
true );
9093 zone->SetDoNotAllowPads(
false );
9094 zone->SetDoNotAllowFootprints(
false );
9096 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9098 if( token == T_LEFT )
9106 if( token != T_allowed && token != T_not_allowed )
9107 Expecting(
"allowed or not_allowed" );
9109 zone->SetDoNotAllowTracks( token == T_not_allowed );
9115 if( token != T_allowed && token != T_not_allowed )
9116 Expecting(
"allowed or not_allowed" );
9118 zone->SetDoNotAllowVias( token == T_not_allowed );
9124 if( token != T_allowed && token != T_not_allowed )
9125 Expecting(
"allowed or not_allowed" );
9127 zone->SetDoNotAllowZoneFills( token == T_not_allowed );
9133 if( token != T_allowed && token != T_not_allowed )
9134 Expecting(
"allowed or not_allowed" );
9136 zone->SetDoNotAllowPads( token == T_not_allowed );
9142 if( token != T_allowed && token != T_not_allowed )
9143 Expecting(
"allowed or not_allowed" );
9145 zone->SetDoNotAllowFootprints( token == T_not_allowed );
9149 Expecting(
"tracks, vias or copperpour" );
9164 if( token != T_pts )
9167 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9179 zone->AddPolygon( outline );
9183 case T_filled_polygon:
9189 if( token == T_layer )
9195 if( token != T_LEFT )
9196 Expecting( T_LEFT );
9203 filledLayer = zone->GetFirstLayer();
9206 bool island =
false;
9208 if( token == T_island )
9215 if( token != T_pts )
9218 if( !pts.count( filledLayer ) )
9227 zone->SetIsIsland( filledLayer, idx );
9229 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9234 addedFilledPolygons |= !poly.
IsEmpty();
9239 case T_fill_segments:
9243 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9245 if( token != T_LEFT )
9246 Expecting( T_LEFT );
9250 if( token != T_pts )
9254 filledLayer = zone->GetFirstLayer();
9261 legacySegs[filledLayer].push_back( fillSegment );
9271 zone->SetZoneName( FromUTF8() );
9276 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9278 if( token == T_LEFT )
9284 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9286 if( token == T_LEFT )
9294 if( token == T_padvia )
9296 else if( token == T_track_end )
9299 Expecting(
"padvia or track_end" );
9305 Expecting(
"type" );
9312 Expecting(
"teardrop" );
9323 Expecting(
"net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
9324 "fill, polygon, filled_polygon, fill_segments, attr, locked, uuid, or name" );
9328 if( zone->GetNumCorners() > 2 )
9330 if( !zone->IsOnCopperLayer() )
9337 zone->SetBorderDisplayStyle( hatchStyle, hatchPitch,
true );
9340 if( addedFilledPolygons )
9342 if( isStrokedFill && !zone->GetIsRuleArea() )
9346 m_parseWarnings.push_back(
_(
"Legacy zone fill strategy is not supported anymore.\n"
9347 "Zone fills will be converted on best-effort basis." ) );
9352 if( zone->GetMinThickness() > 0 )
9354 for(
auto& [layer, polyset] : pts )
9356 polyset.InflateWithLinkedHoles( zone->GetMinThickness() / 2,
9363 for(
auto& [layer, polyset] : pts )
9364 zone->SetFilledPolysList( layer, polyset );
9366 zone->CalculateFilledArea();
9368 else if( legacySegs.size() > 0 )
9376 m_parseWarnings.push_back(
_(
"The legacy segment zone fill mode is no longer supported.\n"
9377 "Zone fills will be converted on a best-effort basis." ) );
9383 for(
const auto& [layer, segments] : legacySegs )
9387 if( zone->HasFilledPolysForLayer( layer ) )
9390 for(
const auto& seg : segments )
9401 zone->SetFilledPolysList( layer, layerFill );
9402 zone->CalculateFilledArea();
9410 bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsRuleArea();
9416 if( !legacyNetnameFromFile.IsEmpty() && zone->GetNetname() != legacyNetnameFromFile )
9429 int newnetcode =
m_board->GetNetCount();
9442 m_board->SetLegacyTeardrops(
true );
9445 zone->SetNeedRefill(
false );
9447 return zone.release();
9453 wxCHECK_MSG( CurTok() == T_point,
nullptr,
9454 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_POINT." ) );
9456 std::unique_ptr<PCB_POINT> point = std::make_unique<PCB_POINT>(
nullptr );
9458 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
9460 if( token == T_LEFT )
9470 point->SetPosition( pt );
9493 default: Expecting(
"at, size, layer or uuid" );
9497 return point.release();
9503 wxCHECK_MSG( CurTok() == T_target,
nullptr,
9504 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TARGET." ) );
9509 std::unique_ptr<PCB_TARGET> target = std::make_unique<PCB_TARGET>(
nullptr );
9511 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9513 if( token == T_LEFT )
9519 target->SetShape( 1 );
9523 target->SetShape( 0 );
9529 target->SetPosition( pt );
9556 Expecting(
"x, plus, at, size, width, layer, uuid, or tstamp" );
9560 return target.release();
9567 std::string idStr( CurStr() );
9570 if( *idStr.begin() ==
'"' && *idStr.rbegin() ==
'"' )
9571 idStr = idStr.substr( 1, idStr.length() - 1 );
9580 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).
void parseCONSTRAINT(BOARD_ITEM *aParent)
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
std::vector< CONSTRAINT_INFO > m_constraintInfos
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)
void resolveConstraints(BOARD_ITEM *aParent)
The type of progress bar timeout.
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_IO_ERRORF(msg,...)
#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.
PCB_CONSTRAINT_TYPE ConstraintTypeFromToken(const wxString &aToken)
Parse a constraint-type token; returns UNDEFINED for an unknown token.
bool ConstraintValueIsLength(PCB_CONSTRAINT_TYPE aType)
True if this type's value is a length in IU (serialized in mm); false for an angle in degrees.
CONSTRAINT_ANCHOR ConstraintAnchorFromToken(const wxString &aToken)
Parse an anchor token; returns WHOLE for an unknown token.
CONSTRAINT_ANCHOR
Which feature of a referenced board item participates in a constraint.
@ VERTEX
An indexed rectangle corner or polygon outline vertex; pairs with CONSTRAINT_MEMBER::m_index.
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.
One participant in a constraint: a referenced board item plus the feature of that item that participa...
KIID m_item
Referenced board item, usually a PCB_SHAPE.
CONSTRAINT_ANCHOR m_anchor
Which feature of that item participates.
int m_index
Vertex ordinal; only meaningful for the VERTEX anchor.
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,...
Deferred constraint, resolved against the parsed items once the whole file is read,...
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)
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.
@ THERMAL
Use thermal relief for pads.
@ THT_THERMAL
Thermal relief only for THT pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper