35#include <fmt/format.h>
43#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 wxCHECK_MSG( CurTok() == T_model,
nullptr,
913 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FP_3DMODEL." ) );
918 NeedSYMBOLorNUMBER();
921 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
923 if( token == T_LEFT )
1000 if( token != T_xyz )
1012 Expecting(
"at, hide, opacity, offset, scale, or rotate" );
1029 if( CurTok() != T_LEFT )
1032 if( NextTok() != T_kicad_pcb)
1049 std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
1054 Unexpected( token );
1056 if( token != T_LEFT )
1057 Expecting( T_LEFT );
1078 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
1088 textItem->ResolveFont( embeddedFonts );
1117 std::map<wxString, wxString> properties;
1131 std::vector<BOARD_ITEM*> bulkAddedItems;
1134 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1138 if( token != T_LEFT )
1139 Expecting( T_LEFT );
1150 m_board->SetGenerator( FromUTF8() );
1161 m_board->SetGenerator( FromUTF8() );
1165 case T_generator_version:
1215 m_board->m_LegacyNetclassesLoaded =
true;
1226 bulkAddedItems.push_back( item );
1232 bulkAddedItems.push_back( item );
1238 bulkAddedItems.push_back( item );
1244 bulkAddedItems.push_back( item );
1250 bulkAddedItems.push_back( item );
1256 bulkAddedItems.push_back( item );
1262 bulkAddedItems.push_back( item );
1269 bulkAddedItems.push_back( item );
1276 bulkAddedItems.push_back( track );
1285 bulkAddedItems.push_back( arc );
1301 bulkAddedItems.push_back( item );
1307 bulkAddedItems.push_back( item );
1313 bulkAddedItems.push_back( item );
1319 bulkAddedItems.push_back( item );
1322 case T_embedded_fonts:
1329 case T_embedded_files:
1332 embeddedFilesParser.SyncLineReaderWith( *
this );
1343 SyncLineReaderWith( embeddedFilesParser );
1349 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
1354 if( bulkAddedItems.size() > 0 )
1355 m_board->FinalizeBulkAdd( bulkAddedItems );
1357 m_board->SetProperties( properties );
1362 wxString msg, undefinedLayerNames, destLayerName;
1366 if( !undefinedLayerNames.IsEmpty() )
1367 undefinedLayerNames += wxT(
", " );
1369 undefinedLayerNames += layerName;
1372 destLayerName =
m_board->GetLayerName( destLayer );
1376 msg.Printf(
_(
"Items found on undefined layers (%s).\n"
1377 "Do you wish to rescue them to the %s layer?\n"
1379 "Zones will need to be refilled." ),
1380 undefinedLayerNames, destLayerName );
1391 const auto visitItem = [&](
BOARD_ITEM& curr_item )
1393 LSET layers = curr_item.GetLayerSet();
1395 if( layers.test(
Rescue ) )
1397 layers.
set( destLayer );
1401 curr_item.SetLayerSet( layers );
1414 via->LayerPair( &top_layer, &bottom_layer );
1418 if( top_layer ==
Rescue )
1421 if( bottom_layer ==
Rescue )
1422 bottom_layer =
B_Cu;
1424 via->SetLayerPair( top_layer, bottom_layer );
1429 visitItem( *track );
1437 visitItem( *drawing );
1441 for(
BOARD_ITEM* drawing : fp->GraphicalItems() )
1442 visitItem( *drawing );
1447 for(
PCB_FIELD* field : fp->GetFields() )
1448 visitItem( *field );
1455 THROW_IO_ERROR( wxT(
"One or more undefined undefinedLayerNames was found; "
1456 "open the board in the PCB Editor to resolve." ) );
1466 ZONE* z =
static_cast<ZONE*
>( zone );
1482 [&](
const KIID& aId )
1486 if(
BOARD* board =
dynamic_cast<BOARD*
>( aParent ) )
1488 aItem = board->ResolveItem( aId,
true );
1492 footprint->RunOnChildren(
1495 if( child->
m_Uuid == aId )
1509 std::vector<const GROUP_INFO*> groupTypeObjects;
1512 groupTypeObjects.emplace_back( &groupInfo );
1515 groupTypeObjects.emplace_back( &genInfo );
1517 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1530 THROW_IO_ERROR( wxString::Format(
_(
"Cannot create generated object of type '%s'" ),
1531 genInfo->genType ) );
1540 group->SetName( groupInfo->name );
1543 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo->uuid;
1545 if( groupInfo->libId.IsValid() )
1546 group->SetDesignBlockLibId( groupInfo->libId );
1548 if( groupInfo->locked )
1549 group->SetLocked(
true );
1557 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1561 for(
const KIID& aUuid : groupInfo->memberUuids )
1568 item = getItem( aUuid );
1574 group->AddItem( item );
1581 m_board->GroupsSanityCheck(
true );
1587 wxCHECK_RET( CurTok() == T_kicad_pcb,
1588 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
1594 if( tok == T_version )
1616 wxCHECK_RET( CurTok() == T_general,
1617 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a general section." ) );
1621 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1623 if( token != T_LEFT )
1624 Expecting( T_LEFT );
1635 case T_legacy_teardrops:
1640 while( ( token = NextTok() ) != T_RIGHT )
1642 if( !IsSymbol( token ) && token != T_NUMBER )
1643 Expecting(
"symbol or number" );
1652 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200119 ) || CurTok() == T_paper,
1653 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
1660 wxString pageType = FromUTF8();
1662 if( !pageInfo.
SetType( pageType ) )
1665 err.Printf(
_(
"Page type '%s' is not valid." ), FromUTF8() );
1692 if( token == T_portrait )
1697 else if( token != T_RIGHT )
1699 Expecting(
"portrait|)" );
1702 m_board->SetPageSettings( pageInfo );
1708 wxCHECK_RET( CurTok() == T_title_block,
1709 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as TITLE_BLOCK." ) );
1714 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1716 if( token != T_LEFT )
1717 Expecting( T_LEFT );
1730 titleBlock.
SetDate( FromUTF8() );
1745 int commentNumber =
parseInt(
"comment" );
1747 switch( commentNumber )
1796 err.Printf( wxT(
"%d is not a valid title block comment number" ), commentNumber );
1804 Expecting(
"title, date, rev, company, or comment" );
1810 m_board->SetTitleBlock( titleBlock );
1819 std::string userName;
1821 bool isVisible =
true;
1825 if( CurTok() != T_LEFT )
1826 Expecting( T_LEFT );
1829 int layer_num =
parseInt(
"layer index" );
1831 NeedSYMBOLorNUMBER();
1840 if( token == T_hide )
1845 else if( token == T_STRING )
1847 userName = CurText();
1850 else if( token != T_RIGHT )
1852 Expecting(
"hide, user defined name, or )" );
1855 aLayer->
m_type = LAYER::ParseType( type.c_str() );
1875 int dielectric_idx = 1;
1878 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1880 if( CurTok() != T_LEFT )
1881 Expecting( T_LEFT );
1885 if( token != T_layer )
1889 case T_copper_finish:
1895 case T_edge_plating:
1901 case T_dielectric_constraints:
1907 case T_edge_connector:
1911 if( token == T_yes )
1913 else if( token == T_bevelled )
1919 case T_castellated_pads:
1953 else if( !( layerId & 1 ) )
1966 stackup.
Add( item );
1970 Expecting(
"layer_name" );
1973 bool has_next_sublayer =
true;
1974 int sublayer_idx = 0;
1977 while( has_next_sublayer )
1979 has_next_sublayer =
false;
1981 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1983 if( token == T_addsublayer )
1985 has_next_sublayer =
true;
1989 if( token == T_LEFT )
2005 if( token == T_LEFT )
2008 if( token == T_locked )
2031 case T_loss_tangent:
2051 wxColour wx_color = color.
ToColour();
2054 name.Printf( wxT(
"#%02X%02X%02X%02X" ),
2074 if( has_next_sublayer )
2082 if( token != T_RIGHT )
2088 m_board->GetDesignSettings().m_HasStackup =
true;
2099 aMap[
"Adesivo.Retro"] =
"B.Adhes";
2100 aMap[
"Adesivo.Fronte"] =
"F.Adhes";
2101 aMap[
"Pasta.Retro"] =
"B.Paste";
2102 aMap[
"Pasta.Fronte"] =
"F.Paste";
2103 aMap[
"Serigrafia.Retro"] =
"B.SilkS";
2104 aMap[
"Serigrafia.Fronte"] =
"F.SilkS";
2105 aMap[
"Maschera.Retro"] =
"B.Mask";
2106 aMap[
"Maschera.Fronte"] =
"F.Mask";
2107 aMap[
"Grafica"] =
"Dwgs.User";
2108 aMap[
"Commenti"] =
"Cmts.User";
2109 aMap[
"Eco1"] =
"Eco1.User";
2110 aMap[
"Eco2"] =
"Eco2.User";
2111 aMap[
"Contorno.scheda"] =
"Edge.Cuts";
2114 aMap[
"Kleju_Dolna"] =
"B.Adhes";
2115 aMap[
"Kleju_Gorna"] =
"F.Adhes";
2116 aMap[
"Pasty_Dolna"] =
"B.Paste";
2117 aMap[
"Pasty_Gorna"] =
"F.Paste";
2118 aMap[
"Opisowa_Dolna"] =
"B.SilkS";
2119 aMap[
"Opisowa_Gorna"] =
"F.SilkS";
2120 aMap[
"Maski_Dolna"] =
"B.Mask";
2121 aMap[
"Maski_Gorna"] =
"F.Mask";
2122 aMap[
"Rysunkowa"] =
"Dwgs.User";
2123 aMap[
"Komentarzy"] =
"Cmts.User";
2124 aMap[
"ECO1"] =
"Eco1.User";
2125 aMap[
"ECO2"] =
"Eco2.User";
2126 aMap[
"Krawedziowa"] =
"Edge.Cuts";
2129 aMap[
"Dessous.Adhes"] =
"B.Adhes";
2130 aMap[
"Dessus.Adhes"] =
"F.Adhes";
2131 aMap[
"Dessous.Pate"] =
"B.Paste";
2132 aMap[
"Dessus.Pate"] =
"F.Paste";
2133 aMap[
"Dessous.SilkS"] =
"B.SilkS";
2134 aMap[
"Dessus.SilkS"] =
"F.SilkS";
2135 aMap[
"Dessous.Masque"] =
"B.Mask";
2136 aMap[
"Dessus.Masque"] =
"F.Mask";
2137 aMap[
"Dessin.User"] =
"Dwgs.User";
2138 aMap[
"Contours.Ci"] =
"Edge.Cuts";
2144 wxCHECK_RET( CurTok() == T_layers,
2145 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layers." ) );
2150 int copperLayerCount = 0;
2152 bool anyHidden =
false;
2154 std::unordered_map< std::string, std::string > v3_layer_names;
2155 std::vector<LAYER> cu;
2159 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2166 cu.push_back( layer );
2179 for(
size_t i = 1; i < cu.size() - 1; i++ )
2184 tmpLayer = ( i + 1 ) * 2;
2186 cu[i].m_number = tmpLayer;
2189 cu[0].m_number =
F_Cu;
2190 cu[cu.size()-1].m_number =
B_Cu;
2192 for(
auto& cu_layer : cu )
2194 enabledLayers.
set( cu_layer.m_number );
2196 if( cu_layer.m_visible )
2197 visibleLayers.
set( cu_layer.m_number );
2209 copperLayerCount = cu.size();
2213 while( token != T_RIGHT )
2219 auto new_layer_it = v3_layer_names.find( layer.
m_name.ToStdString() );
2221 if( new_layer_it != v3_layer_names.end() )
2227 error.Printf(
_(
"Layer '%s' in file '%s' at line %d is not in fixed layer hash." ),
2240 layer.
m_name = it->first;
2251 m_board->SetLayerDescr( it->second, layer );
2255 if( token != T_LEFT )
2262 if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
2264 wxString err = wxString::Format(
_(
"%d is not a valid layer count" ), copperLayerCount );
2269 m_board->SetCopperLayerCount( copperLayerCount );
2270 m_board->SetEnabledLayers( enabledLayers );
2275 m_board->m_LegacyVisibleLayers = visibleLayers;
2281 LSET_MAP::const_iterator it = aMap.find( curText );
2283 if( it == aMap.end() )
2293 LAYER_ID_MAP::const_iterator it = aMap.find( curText );
2295 if( it == aMap.end() )
2302 if( it->second ==
Rescue )
2312 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layer." ) );
2326 wxCHECK_MSG( CurTok() == T_layers,
LSET(),
2327 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as item layers." ) );
2331 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
2345 Expecting(
"single copper layer" );
2348 Expecting(
"max one soldermask layer" );
2353 Expecting(
"no mask layer when track is on internal layer" );
2357 Expecting(
"copper and mask on the same side" );
2360 Expecting(
"copper and mask on the same side" );
2368 wxCHECK_RET( CurTok() == T_setup,
2369 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as setup." ) );
2379 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
2381 if( token != T_LEFT )
2382 Expecting( T_LEFT );
2392 case T_last_trace_width:
2397 case T_user_trace_width:
2408 m_board->m_LegacyDesignSettingsLoaded =
true;
2413 case T_trace_clearance:
2414 defaultNetClass->SetClearance(
parseBoardUnits( T_trace_clearance ) );
2415 m_board->m_LegacyDesignSettingsLoaded =
true;
2419 case T_zone_clearance:
2421 m_board->m_LegacyDesignSettingsLoaded =
true;
2425 case T_zone_45_only:
2427 m_board->m_LegacyDesignSettingsLoaded =
true;
2431 case T_clearance_min:
2433 m_board->m_LegacyDesignSettingsLoaded =
true;
2439 m_board->m_LegacyDesignSettingsLoaded =
true;
2445 m_board->m_LegacyDesignSettingsLoaded =
true;
2451 m_board->m_LegacyDesignSettingsLoaded =
true;
2455 case T_via_min_annulus:
2457 m_board->m_LegacyDesignSettingsLoaded =
true;
2461 case T_via_min_size:
2463 m_board->m_LegacyDesignSettingsLoaded =
true;
2467 case T_through_hole_min:
2469 m_board->m_LegacyDesignSettingsLoaded =
true;
2474 case T_via_min_drill:
2476 m_board->m_LegacyDesignSettingsLoaded =
true;
2480 case T_hole_to_hole_min:
2482 m_board->m_LegacyDesignSettingsLoaded =
true;
2499 m_board->m_LegacyDesignSettingsLoaded =
true;
2506 m_board->m_LegacyDesignSettingsLoaded =
true;
2512 m_board->m_LegacyDesignSettingsLoaded =
true;
2516 case T_uvias_allowed:
2518 m_board->m_LegacyDesignSettingsLoaded =
true;
2522 case T_blind_buried_vias_allowed:
2524 m_board->m_LegacyDesignSettingsLoaded =
true;
2528 case T_uvia_min_size:
2530 m_board->m_LegacyDesignSettingsLoaded =
true;
2534 case T_uvia_min_drill:
2536 m_board->m_LegacyDesignSettingsLoaded =
true;
2540 case T_user_diff_pair:
2550 m_board->m_LegacyDesignSettingsLoaded =
true;
2555 case T_segment_width:
2557 m_board->m_LegacyDesignSettingsLoaded =
true;
2563 m_board->m_LegacyDesignSettingsLoaded =
true;
2567 case T_mod_edge_width:
2569 m_board->m_LegacyDesignSettingsLoaded =
true;
2573 case T_pcb_text_width:
2575 m_board->m_LegacyDesignSettingsLoaded =
true;
2579 case T_mod_text_width:
2581 m_board->m_LegacyDesignSettingsLoaded =
true;
2585 case T_pcb_text_size:
2588 m_board->m_LegacyDesignSettingsLoaded =
true;
2592 case T_mod_text_size:
2595 m_board->m_LegacyDesignSettingsLoaded =
true;
2601 m_board->m_LegacyDesignSettingsLoaded =
true;
2610 m_board->m_LegacyDesignSettingsLoaded =
true;
2619 m_board->m_LegacyDesignSettingsLoaded =
true;
2624 case T_pad_to_mask_clearance:
2629 case T_solder_mask_min_width:
2634 case T_pad_to_paste_clearance:
2639 case T_pad_to_paste_clearance_ratio:
2644 case T_allow_soldermask_bridges_in_footprints:
2687 case T_aux_axis_origin:
2711 case T_visible_elements:
2718 for(
size_t i = 0; i <
sizeof( int ) * CHAR_BIT; i++ )
2719 m_board->m_LegacyVisibleItems.set( i, visible & ( 1u << i ) );
2727 m_board->m_LegacyDesignSettingsLoaded =
true;
2731 case T_filled_areas_thickness:
2737 case T_pcbplotparams:
2743 parser.SyncLineReaderWith( *
this );
2745 plotParams.
Parse( &parser );
2746 SyncLineReaderWith( parser );
2748 m_board->SetPlotOptions( plotParams );
2753 m_board->GetDesignSettings().m_TentViasFront = tent;
2754 m_board->GetDesignSettings().m_TentViasBack = tent;
2759 case T_zone_defaults:
2764 Unexpected( CurText() );
2770 if( !
m_board->GetDesignSettings().m_HasStackup )
2783 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2785 if( token != T_LEFT )
2787 Expecting( T_LEFT );
2798 Unexpected( CurText() );
2805 std::map<PCB_LAYER_ID, ZONE_LAYER_PROPERTIES>& aProperties )
2812 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2814 if( token != T_LEFT )
2816 Expecting( T_LEFT );
2827 case T_hatch_position:
2834 Unexpected( CurText() );
2839 aProperties.emplace( layer, properties );
2847 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2849 if( token != T_LEFT )
2850 Expecting( T_LEFT );
2856 case T_edge_clearance:
2858 m_board->m_LegacyCopperEdgeClearanceLoaded =
true;
2862 case T_copper_line_width:
2867 case T_copper_text_dims:
2871 case T_courtyard_line_width:
2876 case T_edge_cuts_line_width:
2881 case T_silk_line_width:
2886 case T_silk_text_dims:
2890 case T_fab_layers_line_width:
2895 case T_fab_layers_text_dims:
2899 case T_other_layers_line_width:
2904 case T_other_layers_text_dims:
2908 case T_dimension_units:
2914 case T_dimension_precision:
2921 Unexpected( CurText() );
2931 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2933 if( token == T_LEFT )
2953 case T_keep_upright:
2958 Expecting(
"size, thickness, italic or keep_upright" );
2966 wxCHECK_RET( CurTok() == T_net,
2967 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net." ) );
2969 int netCode =
parseInt(
"net number" );
2971 NeedSYMBOLorNUMBER();
2972 wxString
name = FromUTF8();
2997 wxCHECK_RET( CurTok() == T_net_class,
2998 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net class." ) );
3002 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( wxEmptyString );
3005 NeedSYMBOLorNUMBER();
3006 nc->SetName( FromUTF8() );
3008 nc->SetDescription( FromUTF8() );
3010 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3012 if( token != T_LEFT )
3013 Expecting( T_LEFT );
3043 case T_diff_pair_width:
3047 case T_diff_pair_gap:
3053 NeedSYMBOLorNUMBER();
3055 wxString netName = FromUTF8();
3062 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment(
3063 netName, nc->GetName() );
3069 Expecting(
"clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, "
3070 "diff_pair_width, diff_pair_gap or add_net" );
3076 std::shared_ptr<NET_SETTINGS>& netSettings =
m_board->GetDesignSettings().m_NetSettings;
3078 if( netSettings->HasNetclass( nc->GetName() ) )
3083 error.Printf(
_(
"Duplicate NETCLASS name '%s' in file '%s' at line %d, offset %d." ),
3084 nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(),
3088 else if( nc->GetName() == netSettings->GetDefaultNetclass()->GetName() )
3090 netSettings->SetDefaultNetclass( nc );
3094 netSettings->SetNetclass( nc->GetName(), nc );
3101 wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
3102 CurTok() == T_fp_rect || CurTok() == T_fp_line || CurTok() == T_fp_poly ||
3103 CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
3104 CurTok() == T_gr_rect || CurTok() == T_gr_bbox || CurTok() == T_gr_line ||
3105 CurTok() == T_gr_poly || CurTok() == T_gr_vector,
nullptr,
3106 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_SHAPE." ) );
3111 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aParent );
3120 if( token == T_locked )
3122 shape->SetLocked(
true );
3126 if( token != T_LEFT )
3127 Expecting( T_LEFT );
3134 if( token != T_start )
3135 Expecting( T_start );
3139 shape->SetCenter( pt );
3145 if( token != T_end )
3150 shape->SetStart( pt );
3155 if( token != T_angle )
3156 Expecting( T_angle );
3163 VECTOR2I arc_start, arc_mid, arc_end;
3165 if( token != T_start )
3166 Expecting( T_start );
3174 if( token != T_mid )
3183 if( token != T_end )
3190 shape->SetArcGeometry( arc_start, arc_mid, arc_end );
3200 if( token == T_locked )
3202 shape->SetLocked(
true );
3206 if( token != T_LEFT )
3207 Expecting( T_LEFT );
3211 if( token != T_center )
3212 Expecting( T_center );
3216 shape->SetStart( pt );
3222 if( token != T_end )
3227 shape->SetEnd( pt );
3236 if( token == T_locked )
3238 shape->SetLocked(
true );
3242 if( token != T_LEFT )
3243 Expecting( T_LEFT );
3247 if( token != T_pts )
3251 shape->SetBezierC1(
parseXY());
3252 shape->SetBezierC2(
parseXY());
3256 shape->RebuildBezierToSegmentsPointsList(
m_board->GetDesignSettings().m_MaxError );
3258 shape->RebuildBezierToSegmentsPointsList(
ARC_HIGH_DEF );
3269 if( token == T_locked )
3271 shape->SetLocked(
true );
3275 if( token != T_LEFT )
3276 Expecting( T_LEFT );
3280 if( token != T_start )
3281 Expecting( T_start );
3285 shape->SetStart( pt );
3290 if( token != T_end )
3295 shape->SetEnd( pt );
3316 if( token == T_locked )
3318 shape->SetLocked(
true );
3322 if( token != T_LEFT )
3323 Expecting( T_LEFT );
3327 if( token != T_start )
3328 Expecting( T_start );
3332 shape->SetStart( pt );
3337 if( token != T_end )
3342 shape->SetEnd( pt );
3350 shape->SetPolyPoints( {} );
3356 if( token == T_locked )
3358 shape->SetLocked(
true );
3362 if( token != T_LEFT )
3363 Expecting( T_LEFT );
3367 if( token != T_pts )
3370 while( (token = NextTok() ) != T_RIGHT )
3379 Expecting(
"fp_arc, fp_circle, fp_curve, fp_line, fp_poly or fp_rect" );
3383 Expecting(
"gr_arc, gr_circle, gr_curve, gr_vector, gr_line, gr_poly, gr_rect or "
3388 bool foundFill =
false;
3390 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3392 if( token != T_LEFT )
3393 Expecting( T_LEFT );
3413 case T_solder_mask_margin:
3414 shape->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
3431 strokeParser.SyncLineReaderWith( *
this );
3434 SyncLineReaderWith( strokeParser );
3448 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3450 if( token == T_LEFT )
3467 default: Expecting(
"yes, no, solid, none, hatch, reverse_hatch or cross_hatch" );
3488 Expecting(
"layer, width, fill, tstamp, uuid, locked, net, status, "
3489 "or solder_mask_margin" );
3500 shape->SetFilled(
true );
3505 shape->SetFilled(
true );
3511 if( stroke.
GetWidth() <= 0 && !shape->IsAnyFill() )
3516 shape->SetStroke( stroke );
3518 if(
FOOTPRINT* parentFP = shape->GetParentFootprint() )
3520 shape->Rotate( { 0, 0 }, parentFP->GetOrientation() );
3521 shape->Move( parentFP->GetPosition() );
3524 return shape.release();
3530 wxCHECK_MSG( CurTok() == T_image,
nullptr,
3531 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a reference image." ) );
3534 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap = std::make_unique<PCB_REFERENCE_IMAGE>( aParent );
3536 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3538 if( token != T_LEFT )
3539 Expecting( T_LEFT );
3550 bitmap->SetPosition( pos );
3579 data.reserve( 1 << 19 );
3581 while( token != T_RIGHT )
3583 if( !IsSymbol( token ) )
3584 Expecting(
"base64 image data" );
3590 wxMemoryBuffer buffer = wxBase64Decode( data );
3603 bitmap->SetLocked(
locked );
3618 Expecting(
"at, layer, scale, data, locked or uuid" );
3622 return bitmap.release();
3628 wxCHECK_MSG( CurTok() == T_gr_text || CurTok() == T_fp_text,
nullptr,
3629 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXT." ) );
3632 std::unique_ptr<PCB_TEXT>
text;
3634 T token = NextTok();
3639 text = std::unique_ptr<PCB_TEXT>( aBaseText );
3654 text = std::make_unique<PCB_TEXT>( parentFP );
3658 THROW_IO_ERROR( wxString::Format(
_(
"Cannot handle footprint text type %s" ),
3666 text = std::make_unique<PCB_TEXT>( aParent );
3670 if( token == T_locked )
3672 text->SetLocked(
true );
3676 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
3677 Expecting(
"text value" );
3679 wxString value = FromUTF8();
3680 value.Replace( wxT(
"%V" ), wxT(
"${VALUE}" ) );
3681 value.Replace( wxT(
"%R" ), wxT(
"${REFERENCE}" ) );
3682 text->SetText( value );
3700 text->SetVisible(
true );
3703 return text.release();
3710 bool hasAngle =
false;
3712 bool hasPos =
false;
3718 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
3720 if( token == T_LEFT )
3735 if( CurTok() == T_NUMBER )
3743 if( parentFP && CurTok() == T_unlocked )
3760 if( token == T_knockout )
3787 Expecting(
"layer, effects, locked, render_cache, uuid or tstamp" );
3803 Expecting(
"layer, effects, locked, render_cache or tstamp" );
3812 case T_render_cache:
3818 Expecting(
"layer, hide, effects, locked, render_cache or tstamp" );
3820 Expecting(
"layer, effects, locked, render_cache or tstamp" );
3850 wxCHECK_MSG( CurTok() == T_barcode,
nullptr,
3851 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_BARCODE." ) );
3853 std::unique_ptr<PCB_BARCODE> barcode = std::make_unique<PCB_BARCODE>( aParent );
3855 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
3857 if( token != T_LEFT )
3858 Expecting( T_LEFT );
3869 barcode->SetPosition( pos );
3872 if( CurTok() == T_NUMBER )
3888 barcode->SetWidth( w );
3889 barcode->SetHeight( h );
3896 if( NextTok() != T_STRING )
3897 Expecting( T_STRING );
3899 barcode->SetText( FromUTF8() );
3906 barcode->SetTextSize( h );
3914 std::string kind = CurText();
3915 if( kind ==
"code39" )
3917 else if( kind ==
"code128" )
3919 else if( kind ==
"datamatrix" || kind ==
"data_matrix" )
3921 else if( kind ==
"qr" || kind ==
"qrcode" )
3923 else if( kind ==
"microqr" || kind ==
"micro_qr" )
3926 Expecting(
"barcode type" );
3934 std::string ecc = CurText();
3935 if( ecc ==
"L" || ecc ==
"l" )
3937 else if( ecc ==
"M" || ecc ==
"m" )
3939 else if( ecc ==
"Q" || ecc ==
"q" )
3941 else if( ecc ==
"H" || ecc ==
"h" )
3944 Expecting(
"ecc level" );
3962 Expecting(
"at, layer, size, text, text_height, type, ecc_level, locked or uuid" );
3966 barcode->AssembleBarcode();
3968 return barcode.release();
3974 wxCHECK_MSG( CurTok() == T_gr_text_box || CurTok() == T_fp_text_box,
nullptr,
3975 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXTBOX." ) );
3977 std::unique_ptr<PCB_TEXTBOX> textbox = std::make_unique<PCB_TEXTBOX>( aParent );
3981 return textbox.release();
3987 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
3988 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
3990 std::unique_ptr<PCB_TABLECELL> cell = std::make_unique<PCB_TABLECELL>( aParent );
3994 return cell.release();
4005 bool foundMargins =
false;
4007 T token = NextTok();
4010 if( token == T_locked )
4016 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
4017 Expecting(
"text value" );
4019 aTextBox->
SetText( FromUTF8() );
4021 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4023 if( token != T_LEFT )
4024 Expecting( T_LEFT );
4044 if( token != T_end )
4060 while( (token = NextTok() ) != T_RIGHT )
4076 strokeParser.SyncLineReaderWith( *
this );
4079 SyncLineReaderWith( strokeParser );
4094 foundMargins =
true;
4106 Expecting(
"locked, start, pts, angle, width, margins, layer, effects, span, "
4107 "render_cache, uuid or tstamp" );
4120 cell->SetColSpan(
parseInt(
"column span" ) );
4121 cell->SetRowSpan(
parseInt(
"row span" ) );
4125 Expecting(
"locked, start, pts, angle, width, stroke, border, margins, knockout, "
4126 "layer, effects, render_cache, uuid or tstamp" );
4143 case T_render_cache:
4150 Expecting(
"locked, start, pts, angle, width, margins, layer, effects, span, "
4151 "render_cache, uuid or tstamp" );
4155 Expecting(
"locked, start, pts, angle, width, stroke, border, margins, knockout,"
4156 "layer, effects, render_cache, uuid or tstamp" );
4177 aTextBox->
Rotate( { 0, 0 }, parentFP->GetOrientation() );
4178 aTextBox->
Move( parentFP->GetPosition() );
4185 wxCHECK_MSG( CurTok() == T_table,
nullptr,
4186 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
4191 std::unique_ptr<PCB_TABLE>
table = std::make_unique<PCB_TABLE>( aParent, -1 );
4193 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4195 if( token != T_LEFT )
4196 Expecting( T_LEFT );
4202 case T_column_count:
4227 case T_column_widths:
4231 while( ( token = NextTok() ) != T_RIGHT )
4241 while( ( token = NextTok() ) != T_RIGHT )
4248 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4250 if( token != T_LEFT )
4251 Expecting( T_LEFT );
4255 if( token != T_table_cell )
4256 Expecting(
"table_cell" );
4264 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4266 if( token != T_LEFT )
4267 Expecting( T_LEFT );
4286 strokeParser.SyncLineReaderWith( *
this );
4289 SyncLineReaderWith( strokeParser );
4291 table->SetBorderStroke( borderStroke );
4296 Expecting(
"external, header or stroke" );
4304 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4306 if( token != T_LEFT )
4307 Expecting( T_LEFT );
4326 strokeParser.SyncLineReaderWith( *
this );
4329 SyncLineReaderWith( strokeParser );
4331 table->SetSeparatorsStroke( separatorsStroke );
4336 Expecting(
"rows, cols, or stroke" );
4344 Expecting(
"columns, layer, col_widths, row_heights, border, separators, header or "
4349 return table.release();
4355 wxCHECK_MSG( CurTok() == T_dimension,
nullptr,
4356 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as DIMENSION." ) );
4360 std::unique_ptr<PCB_DIMENSION_BASE> dim;
4365 if( token == T_locked )
4372 if( token != T_LEFT )
4377 bool isLegacyDimension =
false;
4378 bool isStyleKnown =
false;
4381 if( token == T_width )
4383 isLegacyDimension =
true;
4384 dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
4390 if( token != T_type )
4391 Expecting( T_type );
4395 case T_aligned: dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
break;
4396 case T_orthogonal: dim = std::make_unique<PCB_DIM_ORTHOGONAL>( aParent );
break;
4397 case T_leader: dim = std::make_unique<PCB_DIM_LEADER>( aParent );
break;
4398 case T_center: dim = std::make_unique<PCB_DIM_CENTER>( aParent );
break;
4399 case T_radial: dim = std::make_unique<PCB_DIM_RADIAL>( aParent );
break;
4400 default: wxFAIL_MSG( wxT(
"Cannot parse unknown dimension type " )
4401 + GetTokenString( CurTok() ) );
4411 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4413 if( token != T_LEFT )
4414 Expecting( T_LEFT );
4439 bool is_aligned = dim->GetKeepTextAligned();
4445 dim->SetKeepTextAligned(
false );
4450 if( isLegacyDimension )
4455 dim->SetAutoUnits(
true );
4457 dim->SetUnits( units );
4462 dim->SetKeepTextAligned( is_aligned );
4463 dim->SetTextPositionMode( t_dim_pos );
4474 dim->SetStart( point );
4476 dim->SetEnd( point );
4496 case T_leader_length:
4512 int orientation =
parseInt(
"orthogonal dimension orientation" );
4518 orientation = std::clamp( orientation, 0, 1 );
4527 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4535 NeedSYMBOLorNUMBER();
4536 dim->SetPrefix( FromUTF8() );
4541 NeedSYMBOLorNUMBER();
4542 dim->SetSuffix( FromUTF8() );
4548 int mode =
parseInt(
"dimension units mode" );
4549 mode = std::max( 0, std::min( 4, mode ) );
4555 case T_units_format:
4557 int format =
parseInt(
"dimension units format" );
4558 format = std::clamp( format, 0, 3 );
4569 case T_override_value:
4570 NeedSYMBOLorNUMBER();
4571 dim->SetOverrideTextEnabled(
true );
4572 dim->SetOverrideText( FromUTF8() );
4576 case T_suppress_zeroes:
4581 std::cerr <<
"Unknown format token: " << GetTokenString( token ) << std::endl;
4582 Expecting(
"prefix, suffix, units, units_format, precision, override_value, "
4583 "suppress_zeroes" );
4591 isStyleKnown =
true;
4594 dim->SetKeepTextAligned(
false );
4596 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4604 dim->SetLineThickness(
parseBoardUnits(
"extension line thickness value" ) );
4608 case T_arrow_direction:
4612 if( token == T_inward )
4614 else if( token == T_outward )
4617 Expecting(
"inward or outward" );
4622 case T_arrow_length:
4628 case T_text_position_mode:
4630 int mode =
parseInt(
"text position mode" );
4631 mode = std::max( 0, std::min( 3, mode ) );
4637 case T_extension_height:
4640 wxCHECK_MSG( aligned,
nullptr, wxT(
"Invalid extension_height token" ) );
4646 case T_extension_offset:
4647 dim->SetExtensionOffset(
parseBoardUnits(
"extension offset value" ) );
4651 case T_keep_text_aligned:
4658 wxT(
"Invalid text_frame token" ) );
4662 int textFrame =
parseInt(
"text frame mode" );
4663 textFrame = std::clamp( textFrame, 0, 3 );
4670 Expecting(
"thickness, arrow_length, arrow_direction, text_position_mode, "
4671 "extension_height, extension_offset" );
4684 if( token != T_pts )
4690 dim->SetStart( point );
4704 if( token != T_pts )
4710 dim->SetEnd( point );
4724 if( token == T_pts )
4746 if( token != T_pts )
4760 if( token != T_pts )
4774 if( token != T_pts )
4788 if( token != T_pts )
4802 dim->SetLocked( isLocked );
4807 Expecting(
"layer, tstamp, uuid, gr_text, feature1, feature2, crossbar, arrow1a, "
4808 "arrow1b, arrow2a, or arrow2b" );
4813 dim->SetLocked(
true );
4817 return dim.release();
4839 wxCHECK_MSG( CurTok() == T_module || CurTok() == T_footprint,
nullptr,
4840 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FOOTPRINT." ) );
4848 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
4850 footprint->SetInitialComments( aInitialComments );
4854 footprint->SetStaticComponentClass(
4855 m_board->GetComponentClassManager().GetNoneComponentClass() );
4860 if( !IsSymbol( token ) && token != T_NUMBER )
4861 Expecting(
"symbol|number" );
4867 THROW_IO_ERROR( wxString::Format(
_(
"Invalid footprint ID in\nfile: %s\nline: %d\n"
4869 CurSource(), CurLineNumber(), CurOffset() ) );
4882 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4884 if( token == T_LEFT )
4894 int this_version =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
4899 footprint->SetFileFormatVersionAtLoad( this_version );
4910 case T_generator_version:
4963 footprint->SetPosition( pt );
4966 if( token == T_NUMBER )
4971 else if( token != T_RIGHT )
4973 Expecting( T_RIGHT );
4979 NeedSYMBOLorNUMBER();
4980 footprint->SetLibDescription( FromUTF8() );
4985 NeedSYMBOLorNUMBER();
4986 footprint->SetKeywords( FromUTF8() );
4993 wxString pName = FromUTF8();
4995 wxString pValue = FromUTF8();
5003 if( pName ==
"ki_keywords" || pName ==
"ki_locked" )
5011 if( pName ==
"ki_description" )
5019 if( pName ==
"Sheetfile" || pName ==
"Sheet file" )
5021 footprint->SetSheetfile( pValue );
5026 if( pName ==
"Sheetname" || pName ==
"Sheet name" )
5028 footprint->SetSheetname( pValue );
5035 std::unique_ptr<PCB_FIELD> unusedField;
5039 if( pName ==
"ki_fp_filters" )
5041 footprint->SetFilters( pValue );
5046 unusedField = std::make_unique<PCB_FIELD>( footprint.get(),
FIELD_T::USER );
5047 field = unusedField.get();
5049 else if( pName ==
"Footprint" )
5055 field = unusedField.get();
5057 else if( footprint->HasField( pName ) )
5059 field = footprint->GetField( pName );
5065 footprint->Add( field );
5086 NeedSYMBOLorNUMBER();
5087 footprint->SetPath(
KIID_PATH( FromUTF8() ) );
5093 footprint->SetSheetname( FromUTF8() );
5099 footprint->SetSheetfile( FromUTF8() );
5105 std::vector<FOOTPRINT::FP_UNIT_INFO> unitInfos;
5108 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5110 if( token == T_LEFT )
5113 if( token == T_unit )
5117 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5119 if( token == T_LEFT )
5122 if( token == T_name )
5124 NeedSYMBOLorNUMBER();
5125 info.m_unitName = FromUTF8();
5128 else if( token == T_pins )
5131 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5133 if( token == T_STRING || token == T_NUMBER )
5135 info.m_pins.emplace_back( FromUTF8() );
5139 Expecting(
"pin number" );
5150 unitInfos.push_back(
info );
5159 if( !unitInfos.empty() )
5160 footprint->SetUnitInfo( unitInfos );
5165 case T_autoplace_cost90:
5166 case T_autoplace_cost180:
5167 parseInt(
"legacy auto-place cost" );
5171 case T_private_layers:
5175 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5180 privateLayers.
set( it->second );
5182 Expecting(
"layer name" );
5191 footprint->SetPrivateLayers( privateLayers );
5195 case T_net_tie_pad_groups:
5196 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5197 footprint->AddNetTiePadGroup( CurStr() );
5201 case T_duplicate_pad_numbers_are_jumpers:
5202 footprint->SetDuplicatePadNumbersAreJumpers(
parseBool() );
5206 case T_jumper_pad_groups:
5209 std::vector<std::set<wxString>>& groups = footprint->JumperPadGroups();
5210 std::set<wxString>* currentGroup =
nullptr;
5212 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
5214 switch(
static_cast<int>( token ) )
5217 currentGroup = &groups.emplace_back();
5222 currentGroup->insert( FromUTF8() );
5227 currentGroup =
nullptr;
5231 Expecting(
"list of pad names" );
5238 case T_solder_mask_margin:
5239 footprint->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
5244 footprint->SetLocalSolderMaskMargin( {} );
5248 case T_solder_paste_margin:
5249 footprint->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
5254 footprint->SetLocalSolderPasteMargin( {} );
5258 case T_solder_paste_ratio:
5259 case T_solder_paste_margin_ratio:
5260 footprint->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
5265 footprint->SetLocalSolderPasteMarginRatio( {} );
5270 footprint->SetLocalClearance(
parseBoardUnits(
"local clearance value" ) );
5275 footprint->SetLocalClearance( {} );
5279 case T_zone_connect:
5284 case T_thermal_width:
5292 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5300 case T_through_hole:
5312 case T_exclude_from_pos_files:
5316 case T_exclude_from_bom:
5320 case T_allow_missing_courtyard:
5321 footprint->SetAllowMissingCourtyard(
true );
5328 case T_allow_soldermask_bridges:
5329 footprint->SetAllowSolderMaskBridges(
true );
5333 Expecting(
"through_hole, smd, virtual, board_only, exclude_from_pos_files, "
5334 "exclude_from_bom or allow_solder_mask_bridges" );
5346 switch( field->GetId() )
5350 const_cast<KIID&
>( footprint->Reference().m_Uuid ) =
text->m_Uuid;
5356 const_cast<KIID&
>( footprint->Value().m_Uuid ) =
text->m_Uuid;
5433 footprint->Add3DModel(
model );
5455 case T_embedded_fonts:
5457 footprint->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
5462 case T_embedded_files:
5465 embeddedFilesParser.SyncLineReaderWith( *
this );
5469 embeddedFilesParser.
ParseEmbedded( footprint->GetEmbeddedFiles() );
5476 SyncLineReaderWith( embeddedFilesParser );
5480 case T_component_classes:
5482 std::unordered_set<wxString> componentClassNames;
5484 while( ( token = NextTok() ) != T_RIGHT )
5486 if( token != T_LEFT )
5487 Expecting( T_LEFT );
5489 if( ( token = NextTok() ) != T_class )
5490 Expecting( T_class );
5492 NeedSYMBOLorNUMBER();
5493 componentClassNames.insert(
From_UTF8( CurText() ) );
5497 footprint->SetTransientComponentClassNames( componentClassNames );
5500 footprint->ResolveComponentClassNames(
m_board, componentClassNames );
5510 Expecting(
"at, descr, locked, placed, tedit, tstamp, uuid, "
5511 "autoplace_cost90, autoplace_cost180, attr, clearance, "
5512 "embedded_files, fp_arc, fp_circle, fp_curve, fp_line, fp_poly, "
5513 "fp_rect, fp_text, pad, group, generator, model, path, solder_mask_margin, "
5514 "solder_paste_margin, solder_paste_margin_ratio, tags, thermal_gap, "
5515 "version, zone, zone_connect, or component_classes" );
5519 footprint->FixUpPadsForBoard(
m_board );
5531 if( footprint->GetKeywords().StartsWith( wxT(
"net tie" ) ) )
5535 for(
PAD*
pad : footprint->Pads() )
5537 if( !padGroup.IsEmpty() )
5538 padGroup += wxS(
", " );
5540 padGroup +=
pad->GetNumber();
5543 if( !padGroup.IsEmpty() )
5544 footprint->AddNetTiePadGroup( padGroup );
5548 footprint->SetAttributes( attributes );
5550 footprint->SetFPID( fpid );
5552 return footprint.release();
5558 wxCHECK_RET( CurTok() == T_stackup,
"Expected stackup token" );
5564 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
5566 if( CurTok() != T_LEFT )
5567 Expecting( T_LEFT );
5575 NeedSYMBOLorNUMBER();
5580 Expecting(
"layer name" );
5584 layers.
set( it->second );
5592 Expecting(
"layer" );
5602 if( gotCuLayers.count() % 2 != 0 )
5605 "odd number of copper layers (%d)." ),
5606 gotCuLayers.count() ) );
5610 if( gotCuLayers != expectedCuLayers )
5613 "copper layers are not contiguous." ) ) );
5619 "technology layers are implicit in footprints and "
5620 "should not be specified in the stackup." ) ) );
5631 wxCHECK_MSG( CurTok() == T_pad,
nullptr,
5632 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PAD." ) );
5636 bool foundNet =
false;
5637 bool foundNetcode =
false;
5639 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
5641 NeedSYMBOLorNUMBER();
5642 pad->SetNumber( FromUTF8() );
5644 T token = NextTok();
5673 case T_np_thru_hole:
5678 Expecting(
"thru_hole, smd, connect, or np_thru_hole" );
5712 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
5715 std::optional<EDA_ANGLE> thermalBrAngleOverride;
5717 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5719 if( token == T_locked )
5725 if( token != T_LEFT )
5726 Expecting( T_LEFT );
5742 pad->SetFPRelativePosition( pt );
5745 if( token == T_NUMBER )
5750 else if( token != T_RIGHT )
5752 Expecting(
") or angle value" );
5769 bool haveWidth =
false;
5772 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5774 if( token == T_LEFT )
5788 drillSize.
y = drillSize.
x;
5807 Expecting(
"oval, size, or offset" );
5816 pad->SetDrillSize( drillSize );
5828 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5830 if( token != T_LEFT )
5831 Expecting( T_LEFT );
5856 Expecting(
"size or layers" );
5863 case T_tertiary_drill:
5868 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5870 if( token != T_LEFT )
5871 Expecting( T_LEFT );
5896 Expecting(
"size or layers" );
5907 pad->SetLayerSet( layerMask );
5923 _(
"Invalid net ID in\nfile: %s\nline: %d offset: %d" ),
5924 CurSource(), CurLineNumber(), CurOffset() );
5928 foundNetcode =
true;
5934 if( !IsSymbol( token ) )
5936 Expecting(
"net name" );
5942 wxString netName( FromUTF8() );
5951 if( netName !=
m_board->FindNet(
pad->GetNetCode() )->GetNetname() )
5955 _(
"Net name doesn't match ID in\nfile: %s\nline: %d offset: %d" ),
5956 CurSource(), CurLineNumber(), CurOffset() );
5969 pad->SetNet( netinfo );
5977 NeedSYMBOLorNUMBER();
5978 pad->SetPinFunction( FromUTF8() );
5983 NeedSYMBOLorNUMBER();
5984 pad->SetPinType( FromUTF8() );
6004 case T_solder_mask_margin:
6005 pad->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6010 pad->SetLocalSolderMaskMargin( {} );
6014 case T_solder_paste_margin:
6015 pad->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
6020 pad->SetLocalSolderPasteMargin( {} );
6024 case T_solder_paste_margin_ratio:
6025 pad->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
6030 pad->SetLocalSolderPasteMarginRatio( {} );
6040 pad->SetLocalClearance( {} );
6048 case T_zone_connect:
6053 case T_thermal_width:
6054 case T_thermal_bridge_width:
6059 case T_thermal_bridge_angle:
6070 case T_roundrect_rratio:
6076 case T_chamfer_ratio:
6088 bool end_list =
false;
6108 case T_bottom_right:
6118 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
6119 "chamfer_bottom_right" );
6130 while( token != T_RIGHT )
6145 case T_RIGHT:
break;
6149 Expecting(
"pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc"
6150 " pad_prop_heatsink or pad_prop_castellated" );
6167 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6169 if( token == T_LEFT )
6200 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
6207 case T_remove_unused_layers:
6210 pad->SetRemoveUnconnected( remove );
6214 case T_keep_end_layers:
6217 pad->SetKeepTopBottom( keep );
6224 pad->Padstack().FrontOuterLayers().has_solder_mask = front;
6225 pad->Padstack().BackOuterLayers().has_solder_mask = back;
6229 case T_zone_layer_connections:
6236 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6241 Expecting(
"copper layer name" );
6262 case T_front_post_machining:
6266 case T_back_post_machining:
6271 Expecting(
"at, locked, drill, layers, net, die_length, roundrect_rratio, "
6272 "solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, uuid, "
6273 "clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
6274 "pinfunction, pintype, zone_connect, thermal_width, thermal_gap, padstack, "
6275 "teardrops, front_post_machining, or back_post_machining" );
6282 pad->SetNetCode( 0,
true );
6285 if( thermalBrAngleOverride )
6287 pad->SetThermalSpokeAngle( *thermalBrAngleOverride );
6310 if( !
pad->CanHaveNumber() )
6314 pad->SetNumber( wxEmptyString );
6318 if(
pad->GetSizeX() <= 0 ||
pad->GetSizeY() <= 0 )
6323 wxLogWarning(
_(
"Invalid zero-sized pad pinned to %s in\nfile: %s\nline: %d\noffset: %d" ),
6324 wxT(
"1µm" ), CurSource(), CurLineNumber(), CurOffset() );
6327 return pad.release();
6334 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
6336 if( token != T_LEFT )
6337 Expecting( T_LEFT );
6358 Expecting(
"circle or rect" );
6379 Expecting(
"outline or convexhull" );
6387 Expecting(
"anchor or clearance" );
6401 T token = NextTok();
6414 Expecting(
"counterbore or countersink" );
6418 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6420 if( token != T_LEFT )
6421 Expecting( T_LEFT );
6443 Expecting(
"size, depth, or angle" );
6453 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
6455 if( token != T_LEFT )
6456 Expecting( T_LEFT );
6467 case T_front_inner_back:
6476 Expecting(
"front_inner_back or custom" );
6487 if( curText ==
"Inner" )
6491 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
6492 "line: %d\noffset: %d." ),
6493 CurSource(), CurLineNumber(), CurOffset() ) );
6506 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
6507 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
6515 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6517 if( token != T_LEFT )
6518 Expecting( T_LEFT );
6556 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
6567 aPad->
SetSize( curLayer, sz );
6592 case T_roundrect_rratio:
6597 case T_chamfer_ratio:
6612 bool end_list =
false;
6632 case T_bottom_right:
6642 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
6643 "chamfer_bottom_right" );
6653 case T_thermal_bridge_width:
6663 case T_thermal_bridge_angle:
6668 case T_zone_connect:
6670 magic_enum::enum_cast<ZONE_CONNECTION>(
parseInt(
"zone connection value" ) );
6690 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6692 if( token != T_LEFT )
6693 Expecting( T_LEFT );
6732 while( ( token = NextTok() ) != T_RIGHT )
6745 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6747 if( token == T_LEFT )
6778 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
6795 Expecting(
"mode or layer" );
6806 while( ( token = NextTok() ) != T_RIGHT )
6811 KIID uuid( CurStr() );
6819 wxCHECK_RET( CurTok() == T_group,
6820 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
6826 groupInfo.
parent = aParent;
6828 while( ( token = NextTok() ) != T_LEFT )
6830 if( token == T_STRING )
6831 groupInfo.
name = FromUTF8();
6832 else if( token == T_locked )
6835 Expecting(
"group name or locked" );
6838 for( ; token != T_RIGHT; token = NextTok() )
6840 if( token != T_LEFT )
6841 Expecting( T_LEFT );
6859 if( !IsSymbol( token ) && token != T_NUMBER )
6860 Expecting(
"symbol|number" );
6862 wxString
name = FromUTF8();
6866 name.Replace(
"{slash}",
"/" );
6872 if(
static_cast<int>(
name.size() ) > bad_pos )
6874 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
6881 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
6898 Expecting(
"uuid, locked, lib_id, or members" );
6906 wxCHECK_RET( CurTok() == T_generated,
6907 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GENERATOR." ) );
6915 genInfo.
parent = aParent;
6922 if( token != T_uuid && token != T_id )
6923 Expecting( T_uuid );
6929 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6931 if( token != T_LEFT )
6932 Expecting( T_LEFT );
6946 genInfo.
name = FromUTF8();
6952 genInfo.
locked = token == T_yes;
6967 wxString pName = FromUTF8();
6973 genInfo.
properties.emplace( pName, wxAny(
true ) );
6978 genInfo.
properties.emplace( pName, wxAny(
false ) );
6985 genInfo.
properties.emplace( pName, wxAny( pValue ) );
6992 wxString pValue = FromUTF8();
7012 genInfo.
properties.emplace( pName, wxAny( pt ) );
7022 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7031 Expecting(
"xy or pts" );
7038 Expecting(
"a number, symbol, string or (" );
7054 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
7055 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ARC." ) );
7060 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board );
7062 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7065 if( token == T_locked )
7067 arc->SetLocked(
true );
7071 if( token != T_LEFT )
7072 Expecting( T_LEFT );
7081 arc->SetStart( pt );
7113 case T_solder_mask_margin:
7114 arc->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
7140 Expecting(
"start, mid, end, width, layer, solder_mask_margin, net, tstamp, uuid or status" );
7150 return arc.release();
7156 wxCHECK_MSG( CurTok() == T_segment,
nullptr,
7157 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TRACK." ) );
7162 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
7164 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7167 if( token == T_locked )
7169 track->SetLocked(
true );
7173 if( token != T_LEFT )
7174 Expecting( T_LEFT );
7183 track->SetStart( pt );
7190 track->SetEnd( pt );
7208 case T_solder_mask_margin:
7209 track->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
7235 Expecting(
"start, end, width, layer, solder_mask_margin, net, tstamp, uuid or locked" );
7245 return track.release();
7251 wxCHECK_MSG( CurTok() == T_via,
nullptr,
7252 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_VIA." ) );
7257 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
7266 via->Padstack().FrontOuterLayers().has_covering =
false;
7267 via->Padstack().BackOuterLayers().has_covering =
false;
7268 via->Padstack().FrontOuterLayers().has_plugging =
false;
7269 via->Padstack().BackOuterLayers().has_plugging =
false;
7270 via->Padstack().Drill().is_filled =
false;
7271 via->Padstack().Drill().is_capped =
false;
7274 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7277 if( token == T_locked )
7279 via->SetLocked(
true );
7283 if( token == T_LEFT )
7303 via->SetStart( pt );
7325 via->SetLayerPair( layer1, layer2 );
7328 Expecting(
"layer name" );
7338 case T_remove_unused_layers:
7340 via->SetRemoveUnconnected(
true );
7344 case T_keep_end_layers:
7346 via->SetKeepStartEnd(
true );
7350 case T_start_end_only:
7356 case T_zone_layer_connections:
7364 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7369 Expecting(
"copper layer name" );
7388 via->Padstack().FrontOuterLayers().has_solder_mask = front;
7389 via->Padstack().BackOuterLayers().has_solder_mask = back;
7396 via->Padstack().FrontOuterLayers().has_covering = front;
7397 via->Padstack().BackOuterLayers().has_covering = back;
7404 via->Padstack().FrontOuterLayers().has_plugging = front;
7405 via->Padstack().BackOuterLayers().has_plugging = back;
7445 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7447 if( token != T_LEFT )
7448 Expecting( T_LEFT );
7473 Expecting(
"size or layers" );
7480 case T_tertiary_drill:
7485 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7487 if( token != T_LEFT )
7488 Expecting( T_LEFT );
7513 Expecting(
"size or layers" );
7520 case T_front_post_machining:
7524 case T_back_post_machining:
7529 Expecting(
"blind, micro, at, size, drill, layers, net, free, tstamp, uuid, status, "
7530 "teardrops, backdrill, tertiary_drill, front_post_machining, or "
7531 "back_post_machining" );
7535 return via.release();
7539std::pair<std::optional<bool>, std::optional<bool>>
7542 T token = NextTok();
7544 std::optional<bool> front( std::nullopt );
7545 std::optional<bool> back( std::nullopt );
7547 if( token != T_LEFT && aAllowLegacyFormat )
7550 while( token != T_RIGHT )
7552 if( token == T_front )
7556 else if( token == T_back )
7560 else if( token == T_none )
7567 Expecting(
"front, back or none" );
7573 return { front, back };
7576 while( token != T_RIGHT )
7578 if( token != T_LEFT )
7583 if( token == T_front )
7585 else if( token == T_back )
7588 Expecting(
"front or back" );
7595 return { front, back };
7603 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
7605 if( token != T_LEFT )
7606 Expecting( T_LEFT );
7617 case T_front_inner_back:
7626 Expecting(
"front_inner_back or custom" );
7637 if( curText ==
"Inner" )
7641 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
7642 "line: %d\noffset: %d." ),
7643 CurSource(), CurLineNumber(), CurOffset() ) );
7656 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
7657 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
7661 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7663 if( token != T_LEFT )
7664 Expecting( T_LEFT );
7674 padstack.
SetSize( { diameter, diameter }, curLayer );
7681 Expecting(
"size" );
7689 Expecting(
"mode or layer" );
7698 wxCHECK_MSG( CurTok() == T_zone,
nullptr,
7699 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ZONE." ) );
7706 wxString legacyNetnameFromFile;
7709 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
7710 std::map<PCB_LAYER_ID, std::vector<SEG>> legacySegs;
7712 bool addedFilledPolygons =
false;
7718 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aParent );
7720 zone->SetAssignedPriority( 0 );
7725 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7728 if( token == T_locked )
7730 zone->SetLocked(
true );
7734 if( token == T_LEFT )
7744 NeedSYMBOLorNUMBER();
7745 legacyNetnameFromFile = FromUTF8();
7772 if( token != T_none && token != T_edge && token != T_full )
7773 Expecting(
"none, edge, or full" );
7788 zone->SetAssignedPriority(
parseInt(
"zone priority" ) );
7792 case T_connect_pads:
7793 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7795 if( token == T_LEFT )
7808 case T_thru_hole_only:
7818 Expecting(
"yes, no, or clearance" );
7824 case T_min_thickness:
7829 case T_filled_areas_thickness:
7836 isStrokedFill =
false;
7842 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7844 if( token == T_LEFT )
7850 zone->SetIsFilled(
true );
7856 if( token != T_segment && token != T_hatch && token != T_polygon )
7857 Expecting(
"segment, hatch or polygon" );
7875 case T_hatch_thickness:
7885 case T_hatch_orientation:
7888 zone->SetHatchOrientation( orientation );
7893 case T_hatch_smoothing_level:
7894 zone->SetHatchSmoothingLevel(
parseDouble( T_hatch_smoothing_level ) );
7898 case T_hatch_smoothing_value:
7899 zone->SetHatchSmoothingValue(
parseDouble( T_hatch_smoothing_value ) );
7903 case T_hatch_border_algorithm:
7906 if( token != T_hatch_thickness && token != T_min_thickness )
7907 Expecting(
"hatch_thickness or min_thickness" );
7909 zone->SetHatchBorderAlgorithm( token == T_hatch_thickness ? 1 : 0 );
7913 case T_hatch_min_hole_area:
7914 zone->SetHatchHoleMinArea(
parseDouble( T_hatch_min_hole_area ) );
7918 case T_arc_segments:
7928 case T_thermal_bridge_width:
7929 zone->SetThermalReliefSpokeWidth(
parseBoardUnits( T_thermal_bridge_width ) );
7941 if( !zone->GetIsRuleArea() )
7947 if( !zone->GetIsRuleArea() )
7953 Expecting(
"none, chamfer, or fillet" );
7962 if( !zone->GetIsRuleArea() )
7963 zone->SetCornerRadius( tmp );
7968 case T_island_removal_mode:
7969 tmp =
parseInt(
"island_removal_mode" );
7971 if( tmp >= 0 && tmp <= 2 )
7977 case T_island_area_min:
7980 zone->SetMinIslandArea( area *
pcbIUScale.IU_PER_MM );
7986 Expecting(
"mode, arc_segments, thermal_gap, thermal_bridge_width, "
7987 "hatch_thickness, hatch_gap, hatch_orientation, "
7988 "hatch_smoothing_level, hatch_smoothing_value, "
7989 "hatch_border_algorithm, hatch_min_hole_area, smoothing, radius, "
7990 "island_removal_mode, or island_area_min" );
7997 zone->SetIsRuleArea(
true );
7999 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8001 if( token == T_LEFT )
8010 zone->SetPlacementAreaSource( FromUTF8() );
8013 case T_component_class:
8017 zone->SetPlacementAreaSource( FromUTF8() );
8024 zone->SetPlacementAreaSource( FromUTF8() );
8031 if( token == T_yes )
8032 zone->SetPlacementAreaEnabled(
true );
8033 else if( token == T_no )
8034 zone->SetPlacementAreaEnabled(
false );
8036 Expecting(
"yes or no" );
8042 Expecting(
"enabled, sheetname, component_class, or group" );
8054 zone->SetIsRuleArea(
true );
8057 zone->SetDoNotAllowPads(
false );
8058 zone->SetDoNotAllowFootprints(
false );
8060 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8062 if( token == T_LEFT )
8070 if( token != T_allowed && token != T_not_allowed )
8071 Expecting(
"allowed or not_allowed" );
8073 zone->SetDoNotAllowTracks( token == T_not_allowed );
8079 if( token != T_allowed && token != T_not_allowed )
8080 Expecting(
"allowed or not_allowed" );
8082 zone->SetDoNotAllowVias( token == T_not_allowed );
8088 if( token != T_allowed && token != T_not_allowed )
8089 Expecting(
"allowed or not_allowed" );
8091 zone->SetDoNotAllowZoneFills( token == T_not_allowed );
8097 if( token != T_allowed && token != T_not_allowed )
8098 Expecting(
"allowed or not_allowed" );
8100 zone->SetDoNotAllowPads( token == T_not_allowed );
8106 if( token != T_allowed && token != T_not_allowed )
8107 Expecting(
"allowed or not_allowed" );
8109 zone->SetDoNotAllowFootprints( token == T_not_allowed );
8113 Expecting(
"tracks, vias or copperpour" );
8128 if( token != T_pts )
8131 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8140 zone->AddPolygon( outline );
8144 case T_filled_polygon:
8150 if( token == T_layer )
8156 if( token != T_LEFT )
8157 Expecting( T_LEFT );
8164 filledLayer = zone->GetFirstLayer();
8167 bool island =
false;
8169 if( token == T_island )
8176 if( token != T_pts )
8179 if( !pts.count( filledLayer ) )
8188 zone->SetIsIsland( filledLayer, idx );
8190 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8195 addedFilledPolygons |= !poly.
IsEmpty();
8200 case T_fill_segments:
8204 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8206 if( token != T_LEFT )
8207 Expecting( T_LEFT );
8211 if( token != T_pts )
8215 filledLayer = zone->GetFirstLayer();
8222 legacySegs[filledLayer].push_back( fillSegment );
8232 zone->SetZoneName( FromUTF8() );
8237 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8239 if( token == T_LEFT )
8245 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8247 if( token == T_LEFT )
8255 if( token == T_padvia )
8257 else if( token == T_track_end )
8260 Expecting(
"padvia or track_end" );
8266 Expecting(
"type" );
8273 Expecting(
"teardrop" );
8284 Expecting(
"net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
8285 "fill, polygon, filled_polygon, fill_segments, attr, locked, uuid, or name" );
8289 if( zone->GetNumCorners() > 2 )
8291 if( !zone->IsOnCopperLayer() )
8298 zone->SetBorderDisplayStyle( hatchStyle, hatchPitch,
true );
8301 if( addedFilledPolygons )
8303 if( isStrokedFill && !zone->GetIsRuleArea() )
8307 wxLogWarning(
_(
"Legacy zone fill strategy is not supported anymore.\n"
8308 "Zone fills will be converted on best-effort basis." ) );
8313 if( zone->GetMinThickness() > 0 )
8315 for(
auto& [layer, polyset] : pts )
8317 polyset.InflateWithLinkedHoles( zone->GetMinThickness() / 2,
8324 for(
auto& [layer, polyset] : pts )
8325 zone->SetFilledPolysList( layer, polyset );
8327 zone->CalculateFilledArea();
8329 else if( legacySegs.size() > 0 )
8337 wxLogWarning(
_(
"The legacy segment zone fill mode is no longer supported.\n"
8338 "Zone fills will be converted on a best-effort basis." ) );
8344 for(
const auto& [layer, segments] : legacySegs )
8348 if( zone->HasFilledPolysForLayer( layer ) )
8351 for(
const auto& seg : segments )
8362 zone->SetFilledPolysList( layer, layerFill );
8363 zone->CalculateFilledArea();
8371 bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsRuleArea();
8377 if( !legacyNetnameFromFile.IsEmpty() && zone->GetNetname() != legacyNetnameFromFile )
8390 int newnetcode =
m_board->GetNetCount();
8403 m_board->SetLegacyTeardrops(
true );
8406 zone->SetNeedRefill(
false );
8408 return zone.release();
8414 wxCHECK_MSG( CurTok() == T_point,
nullptr,
8415 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_POINT." ) );
8417 std::unique_ptr<PCB_POINT> point = std::make_unique<PCB_POINT>(
nullptr );
8419 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
8421 if( token == T_LEFT )
8431 point->SetPosition( pt );
8454 default: Expecting(
"at, size, layer or uuid" );
8458 return point.release();
8464 wxCHECK_MSG( CurTok() == T_target,
nullptr,
8465 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TARGET." ) );
8470 std::unique_ptr<PCB_TARGET> target = std::make_unique<PCB_TARGET>(
nullptr );
8472 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8474 if( token == T_LEFT )
8480 target->SetShape( 1 );
8484 target->SetShape( 0 );
8490 target->SetPosition( pt );
8517 Expecting(
"x, plus, at, size, width, layer, uuid, or tstamp" );
8521 return target.release();
8528 std::string idStr( CurStr() );
8531 if( *idStr.begin() ==
'"' && *idStr.rbegin() ==
'"' )
8532 idStr = idStr.substr( 1, idStr.length() - 1 );
8541 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)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
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 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 SetThicknessLocked(bool aLocked, 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.
KICAD_T Type() const
Returns the type of object.
virtual EMBEDDED_FILES * GetEmbeddedFiles()
SHAPE_POLY_SET & GetPolyShape()
void SetStart(const VECTOR2I &aStart)
void SetShape(SHAPE_T aShape)
void SetEnd(const VECTOR2I &aEnd)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
const EDA_ANGLE & GetTextAngle() const
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.
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)
void SetLineSpacing(double aLineSpacing)
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)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
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.
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
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 int NameToLayer(wxString &aName)
Return the layer number from a layer name.
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 LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
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.
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()
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 SetOffset(PCB_LAYER_ID aLayer, const VECTOR2I &aOffset)
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 SetSize(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
void SetChamferPositions(PCB_LAYER_ID aLayer, int aPositions)
Has meaning only for chamfered rectangular pads.
void SetRoundRectRadiusRatio(PCB_LAYER_ID aLayer, double aRadiusScale)
Has meaning only for rounded rectangle pads.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
bool SetType(PAGE_SIZE_TYPE aPageSize, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
void SetWidthMM(double aWidthInMM)
void SetHeightMM(double aHeightInMM)
const PAGE_SIZE_TYPE & GetType() const
For better understanding of the points that make a dimension:
void SetExtensionHeight(int aHeight)
void UpdateHeight(const VECTOR2I &aCrossbarStart, const VECTOR2I &aCrossbarEnd)
Update the stored height basing on points coordinates.
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
A leader is a dimension-like object pointing to a specific point.
void SetTextBorder(DIM_TEXT_BORDER aBorder)
An orthogonal dimension is like an aligned dimension, but the extension lines are locked to the X or ...
A radial dimension indicates either the radius or diameter of an arc or circle.
void SetLeaderLength(int aLength)
virtual void SetProperties(const STRING_ANY_MAP &aProps)
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
A set of BOARD_ITEMs (i.e., without duplicates).
wxString m_generatorVersion
Set to the generator version this board requires.
PCB_TABLECELL * parsePCB_TABLECELL(BOARD_ITEM *aParent)
std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP
std::vector< int > m_netCodes
net codes mapping for boards being loaded
void parseOutlinePoints(SHAPE_LINE_CHAIN &aPoly)
Parses possible outline points and stores them into aPoly.
BOARD * parseBOARD_unchecked()
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
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.
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)
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)
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)
FP_3DMODEL * parse3DModel()
LSET parseBoardItemLayersAsMask()
Parse the layers definition of a BOARD_ITEM object.
void resolveGroups(BOARD_ITEM *aParent)
Called after parsing a footprint definition or board to build the group membership lists.
void parseDefaultTextDims(BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
std::vector< GROUP_INFO > m_groupInfos
std::optional< bool > parseOptBool()
ZONE * parseZONE(BOARD_ITEM_CONTAINER *aParent)
PCB_TABLE * parsePCB_TABLE(BOARD_ITEM *aParent)
std::vector< GENERATOR_INFO > m_generatorInfos
PCB_TEXTBOX * parsePCB_TEXTBOX(BOARD_ITEM *aParent)
std::chrono::time_point< CLOCK > TIME_PT
PCB_TEXT * parsePCB_TEXT(BOARD_ITEM *aParent, PCB_TEXT *aBaseText=nullptr)
unsigned m_lineCount
for progress reporting
VECTOR2I parseXY()
Parse a coordinate pair (xy X Y) in board units (mm).
void parseTEARDROP_PARAMETERS(TEARDROP_PARAMETERS *tdParams)
PCB_TRACK * parsePCB_TRACK()
int m_requiredVersion
set to the KiCad format version this board requires
PAD * parsePAD(FOOTPRINT *aParent=nullptr)
std::function< bool(wxString aTitle, int aIcon, wxString aMsg, wxString aAction)> m_queryUserCallback
bool m_showLegacySegmentZoneWarning
void parseNet(BOARD_CONNECTED_ITEM *aItem)
FOOTPRINT * parseFOOTPRINT_unchecked(wxArrayString *aInitialComments=nullptr)
void parseRenderCache(EDA_TEXT *text)
Parse the render cache for any object derived from EDA_TEXT.
TIME_PT m_lastProgressTime
for progress reporting
void parseGROUP_members(GROUP_INFO &aGroupInfo)
bool IsValidBoardHeader()
Partially parse the input and check if it matches expected header.
void parseFootprintVariant(FOOTPRINT *aFootprint)
std::pair< wxString, wxString > parseBoardProperty()
LSET_MAP m_layerMasks
map layer names to their masks
bool parseMaybeAbsentBool(bool aDefaultValue)
Parses a boolean flag inside a list that existed before boolean normalization.
int parseBoardUnits()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
void parseViastack(PCB_VIA *aVia)
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 SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetIsProxyItem(bool aIsProxy=true) override
void SetStroke(const STROKE_PARAMS &aStroke) override
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetBorderEnabled(bool enabled)
void SetMarginTop(int aTop)
void SetMarginLeft(int aLeft)
void SetMarginBottom(int aBottom)
void SetMarginRight(int aRight)
void Move(const VECTOR2I &aMoveVector) override
Move this object.
int GetLegacyTextMargin() const
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings, bool aCheckSide) override
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
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.
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.
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.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
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.
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()
A type-safe container of any type.
constexpr any() noexcept
Default constructor, creates an empty object.
This file is part of the common library.
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
@ RECT_CHAMFER_BOTTOM_RIGHT
@ RECT_CHAMFER_BOTTOM_LEFT
@ ROUND_ALL_CORNERS
All angles are rounded.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FILLED_SHAPE
Fill with object color.
EDA_DATA_TYPE
The type of unit.
const wxChar *const traceKicadPcbPlugin
Flag to enable KiCad PCB plugin debug output.
void ignore_unused(const T &)
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
#define MIN_VISIBILITY_MASK
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API bool FetchUnitsFromString(const wxString &aTextValue, EDA_UNITS &aUnits)
Write any unit info found in the string to aUnits.
KICOMMON_API double GetScaleForInternalUnitType(const EDA_IU_SCALE &aIuScale, EDA_DATA_TYPE aDataType)
Returns the scaling parameter for the given units data type.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
@ FIDUCIAL_LOCAL
a fiducial (usually a smd) local to the parent footprint
@ FIDUCIAL_GLBL
a fiducial (usually a smd) for the full board
@ MECHANICAL
a pad used for mechanical support
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
@ HEATSINK
a pad used as heat sink, usually in SMD footprints
@ NONE
no special fabrication property
@ TESTPOINT
a test point pad
@ CASTELLATED
a pad with a castellated through hole
@ BGA
Smd pad, used in BGA footprints.
#define MAX_PAGE_SIZE_PCBNEW_MM
#define MIN_PAGE_SIZE_MM
Min and max page sizes for clamping, in mm.
BARCODE class definition.
DIM_TEXT_POSITION
Where to place the text on a dimension.
@ MANUAL
Text placement is manually set by the user.
DIM_UNITS_FORMAT
How to display the units in a dimension's text.
DIM_UNITS_MODE
Used for storing the units selection in the file because EDA_UNITS alone doesn't cut it.
DIM_TEXT_BORDER
Frame to show around dimension text.
Class to handle a set of BOARD_ITEMs.
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
#define LEGACY_ARC_FORMATTING
These were the last to use old arc formatting.
#define LEGACY_NET_TIES
These were the last to use the keywords field to indicate a net-tie.
#define BOARD_FILE_HOST_VERSION
Earlier files than this include the host tag.
constexpr double INT_LIMIT
Pcbnew s-expression file format parser definition.
PGM_BASE & Pgm()
The global program "get" accessor.
static bool IsNumber(char x)
double parseDouble(LINE_READER &aReader, const char *aLine, const char **aOutput)
Parses an ASCII point string with possible leading whitespace into a double precision floating point ...
#define DEFAULT_SOLDERMASK_OPACITY
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
wxString From_UTF8(const char *cstring)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Container to handle a stock of specific differential pairs each with unique track width,...
Container to hold information pertinent to a layer of a BOARD.
LAYER_T m_type
The type of the layer.
wxString m_name
The canonical name of the layer.
wxString m_userName
The user defined name of the layer.
int m_number
The layer ID.
! The properties of a padstack drill. Drill position is always the pad position (origin).
VECTOR2I size
Drill diameter (x == y) or slot dimensions (x != y)
std::optional< bool > has_solder_mask
True if this outer layer has mask (is not tented)
std::optional< PAD_DRILL_POST_MACHINING_MODE > mode
A filename or source description, a problem input line, a line number, a byte offset,...
Convert net code using the mapping table if available, otherwise returns unchanged net code if < 0 or...
STRING_ANY_MAP properties
std::vector< KIID > memberUuids
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_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
VECTOR2< int32_t > VECTOR2I
ISLAND_REMOVAL_MODE
Whether or not to remove isolated islands from a zone.
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
ZONE_CONNECTION
How pads are covered by copper in zone.
@ THT_THERMAL
Thermal relief only for THT pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper