35#include <fmt/format.h>
43#include <magic_enum.hpp>
82#include <wx/mstream.h>
91constexpr double INT_LIMIT = std::numeric_limits<int>::max() - 10;
93using namespace PCB_KEYS_T;
133 for(
int i=1; i<=14; ++i )
135 std::string key = fmt::format(
"Inner{}.Cu", i );
146 TIME_PT curTime = CLOCK::now();
147 unsigned curLine = reader->LineNumber();
150 if(
delta > std::chrono::milliseconds( 250 ) )
169 while( ( token = NextTok() ) != T_EOF )
171 if( token == T_LEFT )
174 if( token == T_RIGHT )
191 m_netCodes.resize(
static_cast<std::size_t
>( aIndex ) + 1 );
233 else if( token == T_no )
236 Expecting(
"yes or no" );
248 else if( token == T_no )
250 else if( token == T_none )
253 Expecting(
"yes, no or none" );
264 bool ret = aDefaultValue;
266 if( PrevTok() == T_LEFT )
271 if(
static_cast<int>( token ) ==
DSN_RIGHT )
272 return aDefaultValue;
274 if( token == T_yes || token == T_true )
276 else if( token == T_no || token == T_false )
279 Expecting(
"yes or no" );
286 return aDefaultValue;
295 int token = NextTok();
303 wxLogError(
_(
"Invalid net ID in\nfile: %s;\nline: %d\noffset: %d." ),
304 CurSource(), CurLineNumber(), CurOffset() );
311 if( !IsSymbol( token ) )
313 Expecting(
"net name" );
319 wxString netName( FromUTF8() );
343 int year, month, day;
352 if( day <= 0 || month <= 0 || month > 12 ||
353 day > wxDateTime::GetNumberOfDays( (wxDateTime::Month)( month - 1 ), year ) )
360 wxDateTime date( day, (wxDateTime::Month)( month - 1 ), year, 0, 0, 0, 0 );
361 return date.FormatDate();
367 if( CurTok() != T_LEFT )
387 if( CurTok() != T_LEFT )
406 bool has_start =
false;
407 bool has_mid =
false;
408 bool has_end =
false;
410 VECTOR2I arc_start, arc_mid, arc_end;
412 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
414 if( token != T_LEFT )
440 Expecting(
"start, mid or end" );
447 Expecting(
"start" );
455 SHAPE_ARC arc( arc_start, arc_mid, arc_end, 0 );
459 if( token != T_RIGHT )
460 Expecting( T_RIGHT );
465 Expecting(
"xy or arc" );
502 return { pName, pValue };
512 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
514 if( token == T_LEFT )
523 case T_allow_two_segments:
527 case T_prefer_zone_connections:
531 case T_best_length_ratio:
541 case T_best_width_ratio:
567 Expecting(
"enabled, allow_two_segments, prefer_zone_connections, best_length_ratio, "
568 "max_length, best_width_ratio, max_width, curve_points or filter_ratio" );
576 wxCHECK_RET( CurTok() == T_effects,
577 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as EDA_TEXT." ) );
595 bool foundTextSize =
false;
597 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
599 if( token == T_LEFT )
605 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
607 if( token == T_LEFT )
626 foundTextSize =
true;
649 Expecting(
"face, size, line_spacing, thickness, bold, or italic" );
656 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
658 if( token == T_LEFT )
668 default: Expecting(
"left, right, top, bottom, or mirror" );
685 Expecting(
"font, justify, or hide" );
693 const double defaultTextSize = 1.524 *
pcbIUScale.IU_PER_MM;
704 NeedSYMBOLorNUMBER();
705 wxString cacheText =
From_UTF8( CurText() );
708 text->SetupRenderCache( cacheText,
text->GetFont(), cacheAngle, { 0, 0 } );
710 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
712 if( token != T_LEFT )
717 if( token != T_polygon )
718 Expecting( T_polygon );
722 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
724 if( token != T_LEFT )
734 while( (token = NextTok() ) != T_RIGHT )
745 text->AddRenderCacheGlyph( poly );
752 wxCHECK_MSG( CurTok() == T_model,
nullptr,
753 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FP_3DMODEL." ) );
758 NeedSYMBOLorNUMBER();
761 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
763 if( token == T_LEFT )
852 Expecting(
"at, hide, opacity, offset, scale, or rotate" );
869 if( CurTok() != T_LEFT )
872 if( NextTok() != T_kicad_pcb)
889 std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
896 if( token != T_LEFT )
918 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
928 textItem->ResolveFont( embeddedFonts );
957 std::map<wxString, wxString> properties;
971 std::vector<BOARD_ITEM*> bulkAddedItems;
974 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
978 if( token != T_LEFT )
990 m_board->SetGenerator( FromUTF8() );
1001 m_board->SetGenerator( FromUTF8() );
1005 case T_generator_version:
1051 m_board->m_LegacyNetclassesLoaded =
true;
1062 bulkAddedItems.push_back( item );
1068 bulkAddedItems.push_back( item );
1074 bulkAddedItems.push_back( item );
1080 bulkAddedItems.push_back( item );
1086 bulkAddedItems.push_back( item );
1092 bulkAddedItems.push_back( item );
1098 bulkAddedItems.push_back( item );
1105 bulkAddedItems.push_back( item );
1112 bulkAddedItems.push_back( track );
1121 bulkAddedItems.push_back( arc );
1137 bulkAddedItems.push_back( item );
1143 bulkAddedItems.push_back( item );
1149 bulkAddedItems.push_back( item );
1155 bulkAddedItems.push_back( item );
1158 case T_embedded_fonts:
1165 case T_embedded_files:
1168 embeddedFilesParser.SyncLineReaderWith( *
this );
1176 wxLogError( e.
What() );
1179 SyncLineReaderWith( embeddedFilesParser );
1185 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
1190 if( bulkAddedItems.size() > 0 )
1191 m_board->FinalizeBulkAdd( bulkAddedItems );
1193 m_board->SetProperties( properties );
1198 wxString msg, undefinedLayerNames, destLayerName;
1202 if( !undefinedLayerNames.IsEmpty() )
1203 undefinedLayerNames += wxT(
", " );
1205 undefinedLayerNames += layerName;
1208 destLayerName =
m_board->GetLayerName( destLayer );
1212 msg.Printf(
_(
"Items found on undefined layers (%s).\n"
1213 "Do you wish to rescue them to the %s layer?\n"
1215 "Zones will need to be refilled." ),
1216 undefinedLayerNames, destLayerName );
1227 const auto visitItem = [&](
BOARD_ITEM& curr_item )
1229 LSET layers = curr_item.GetLayerSet();
1231 if( layers.test(
Rescue ) )
1233 layers.
set( destLayer );
1237 curr_item.SetLayerSet( layers );
1250 via->LayerPair( &top_layer, &bottom_layer );
1254 if( top_layer ==
Rescue )
1257 if( bottom_layer ==
Rescue )
1258 bottom_layer =
B_Cu;
1260 via->SetLayerPair( top_layer, bottom_layer );
1265 visitItem( *track );
1273 visitItem( *drawing );
1277 for(
BOARD_ITEM* drawing : fp->GraphicalItems() )
1278 visitItem( *drawing );
1283 for(
PCB_FIELD* field : fp->GetFields() )
1284 visitItem( *field );
1291 THROW_IO_ERROR( wxT(
"One or more undefined undefinedLayerNames was found; "
1292 "open the board in the PCB Editor to resolve." ) );
1302 ZONE* z =
static_cast<ZONE*
>( zone );
1318 [&](
const KIID& aId )
1322 if(
BOARD* board =
dynamic_cast<BOARD*
>( aParent ) )
1324 aItem = board->ResolveItem( aId,
true );
1328 footprint->RunOnChildren(
1331 if( child->
m_Uuid == aId )
1345 std::vector<const GROUP_INFO*> groupTypeObjects;
1348 groupTypeObjects.emplace_back( &groupInfo );
1351 groupTypeObjects.emplace_back( &genInfo );
1353 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1366 THROW_IO_ERROR( wxString::Format(
_(
"Cannot create generated object of type '%s'" ),
1367 genInfo->genType ) );
1376 group->SetName( groupInfo->name );
1379 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo->uuid;
1381 if( groupInfo->libId.IsValid() )
1382 group->SetDesignBlockLibId( groupInfo->libId );
1384 if( groupInfo->locked )
1385 group->SetLocked(
true );
1393 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1397 for(
const KIID& aUuid : groupInfo->memberUuids )
1404 item = getItem( aUuid );
1410 group->AddItem( item );
1417 m_board->GroupsSanityCheck(
true );
1423 wxCHECK_RET( CurTok() == T_kicad_pcb,
1424 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
1430 if( tok == T_version )
1452 wxCHECK_RET( CurTok() == T_general,
1453 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a general section." ) );
1457 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1459 if( token != T_LEFT )
1460 Expecting( T_LEFT );
1471 case T_legacy_teardrops:
1476 while( ( token = NextTok() ) != T_RIGHT )
1478 if( !IsSymbol( token ) && token != T_NUMBER )
1479 Expecting(
"symbol or number" );
1488 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200119 ) || CurTok() == T_paper,
1489 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
1496 wxString pageType = FromUTF8();
1498 if( !pageInfo.
SetType( pageType ) )
1501 err.Printf(
_(
"Page type '%s' is not valid." ), FromUTF8() );
1528 if( token == T_portrait )
1533 else if( token != T_RIGHT )
1535 Expecting(
"portrait|)" );
1538 m_board->SetPageSettings( pageInfo );
1544 wxCHECK_RET( CurTok() == T_title_block,
1545 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as TITLE_BLOCK." ) );
1550 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1552 if( token != T_LEFT )
1553 Expecting( T_LEFT );
1566 titleBlock.
SetDate( FromUTF8() );
1581 int commentNumber =
parseInt(
"comment" );
1583 switch( commentNumber )
1632 err.Printf( wxT(
"%d is not a valid title block comment number" ), commentNumber );
1640 Expecting(
"title, date, rev, company, or comment" );
1646 m_board->SetTitleBlock( titleBlock );
1655 std::string userName;
1657 bool isVisible =
true;
1661 if( CurTok() != T_LEFT )
1662 Expecting( T_LEFT );
1665 int layer_num =
parseInt(
"layer index" );
1667 NeedSYMBOLorNUMBER();
1676 if( token == T_hide )
1681 else if( token == T_STRING )
1683 userName = CurText();
1686 else if( token != T_RIGHT )
1688 Expecting(
"hide, user defined name, or )" );
1691 aLayer->
m_type = LAYER::ParseType( type.c_str() );
1711 int dielectric_idx = 1;
1714 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1716 if( CurTok() != T_LEFT )
1717 Expecting( T_LEFT );
1721 if( token != T_layer )
1725 case T_copper_finish:
1731 case T_edge_plating:
1737 case T_dielectric_constraints:
1743 case T_edge_connector:
1747 if( token == T_yes )
1749 else if( token == T_bevelled )
1755 case T_castellated_pads:
1789 else if( !( layerId & 1 ) )
1802 stackup.
Add( item );
1806 Expecting(
"layer_name" );
1809 bool has_next_sublayer =
true;
1810 int sublayer_idx = 0;
1813 while( has_next_sublayer )
1815 has_next_sublayer =
false;
1817 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1819 if( token == T_addsublayer )
1821 has_next_sublayer =
true;
1825 if( token == T_LEFT )
1841 if( token == T_LEFT )
1844 if( token == T_locked )
1867 case T_loss_tangent:
1887 wxColour wx_color = color.
ToColour();
1890 name.Printf( wxT(
"#%02X%02X%02X%02X" ),
1910 if( has_next_sublayer )
1918 if( token != T_RIGHT )
1924 m_board->GetDesignSettings().m_HasStackup =
true;
1935 aMap[
"Adesivo.Retro"] =
"B.Adhes";
1936 aMap[
"Adesivo.Fronte"] =
"F.Adhes";
1937 aMap[
"Pasta.Retro"] =
"B.Paste";
1938 aMap[
"Pasta.Fronte"] =
"F.Paste";
1939 aMap[
"Serigrafia.Retro"] =
"B.SilkS";
1940 aMap[
"Serigrafia.Fronte"] =
"F.SilkS";
1941 aMap[
"Maschera.Retro"] =
"B.Mask";
1942 aMap[
"Maschera.Fronte"] =
"F.Mask";
1943 aMap[
"Grafica"] =
"Dwgs.User";
1944 aMap[
"Commenti"] =
"Cmts.User";
1945 aMap[
"Eco1"] =
"Eco1.User";
1946 aMap[
"Eco2"] =
"Eco2.User";
1947 aMap[
"Contorno.scheda"] =
"Edge.Cuts";
1950 aMap[
"Kleju_Dolna"] =
"B.Adhes";
1951 aMap[
"Kleju_Gorna"] =
"F.Adhes";
1952 aMap[
"Pasty_Dolna"] =
"B.Paste";
1953 aMap[
"Pasty_Gorna"] =
"F.Paste";
1954 aMap[
"Opisowa_Dolna"] =
"B.SilkS";
1955 aMap[
"Opisowa_Gorna"] =
"F.SilkS";
1956 aMap[
"Maski_Dolna"] =
"B.Mask";
1957 aMap[
"Maski_Gorna"] =
"F.Mask";
1958 aMap[
"Rysunkowa"] =
"Dwgs.User";
1959 aMap[
"Komentarzy"] =
"Cmts.User";
1960 aMap[
"ECO1"] =
"Eco1.User";
1961 aMap[
"ECO2"] =
"Eco2.User";
1962 aMap[
"Krawedziowa"] =
"Edge.Cuts";
1965 aMap[
"Dessous.Adhes"] =
"B.Adhes";
1966 aMap[
"Dessus.Adhes"] =
"F.Adhes";
1967 aMap[
"Dessous.Pate"] =
"B.Paste";
1968 aMap[
"Dessus.Pate"] =
"F.Paste";
1969 aMap[
"Dessous.SilkS"] =
"B.SilkS";
1970 aMap[
"Dessus.SilkS"] =
"F.SilkS";
1971 aMap[
"Dessous.Masque"] =
"B.Mask";
1972 aMap[
"Dessus.Masque"] =
"F.Mask";
1973 aMap[
"Dessin.User"] =
"Dwgs.User";
1974 aMap[
"Contours.Ci"] =
"Edge.Cuts";
1980 wxCHECK_RET( CurTok() == T_layers,
1981 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layers." ) );
1986 int copperLayerCount = 0;
1988 bool anyHidden =
false;
1990 std::unordered_map< std::string, std::string > v3_layer_names;
1991 std::vector<LAYER> cu;
1995 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2002 cu.push_back( layer );
2015 for(
size_t i = 1; i < cu.size() - 1; i++ )
2020 tmpLayer = ( i + 1 ) * 2;
2022 cu[i].m_number = tmpLayer;
2025 cu[0].m_number =
F_Cu;
2026 cu[cu.size()-1].m_number =
B_Cu;
2028 for(
auto& cu_layer : cu )
2030 enabledLayers.
set( cu_layer.m_number );
2032 if( cu_layer.m_visible )
2033 visibleLayers.
set( cu_layer.m_number );
2045 copperLayerCount = cu.size();
2049 while( token != T_RIGHT )
2055 auto new_layer_it = v3_layer_names.find( layer.
m_name.ToStdString() );
2057 if( new_layer_it != v3_layer_names.end() )
2063 error.Printf(
_(
"Layer '%s' in file '%s' at line %d is not in fixed layer hash." ),
2076 layer.
m_name = it->first;
2087 m_board->SetLayerDescr( it->second, layer );
2091 if( token != T_LEFT )
2098 if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
2100 wxString err = wxString::Format(
_(
"%d is not a valid layer count" ), copperLayerCount );
2105 m_board->SetCopperLayerCount( copperLayerCount );
2106 m_board->SetEnabledLayers( enabledLayers );
2111 m_board->m_LegacyVisibleLayers = visibleLayers;
2117 LSET_MAP::const_iterator it = aMap.find( curText );
2119 if( it == aMap.end() )
2129 LAYER_ID_MAP::const_iterator it = aMap.find( curText );
2131 if( it == aMap.end() )
2138 if( it->second ==
Rescue )
2148 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layer." ) );
2162 wxCHECK_MSG( CurTok() == T_layers,
LSET(),
2163 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as item layers." ) );
2167 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
2181 Expecting(
"single copper layer" );
2184 Expecting(
"max one soldermask layer" );
2189 Expecting(
"no mask layer when track is on internal layer" );
2193 Expecting(
"copper and mask on the same side" );
2196 Expecting(
"copper and mask on the same side" );
2204 wxCHECK_RET( CurTok() == T_setup,
2205 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as setup." ) );
2215 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
2217 if( token != T_LEFT )
2218 Expecting( T_LEFT );
2228 case T_last_trace_width:
2233 case T_user_trace_width:
2244 m_board->m_LegacyDesignSettingsLoaded =
true;
2249 case T_trace_clearance:
2250 defaultNetClass->SetClearance(
parseBoardUnits( T_trace_clearance ) );
2251 m_board->m_LegacyDesignSettingsLoaded =
true;
2255 case T_zone_clearance:
2257 m_board->m_LegacyDesignSettingsLoaded =
true;
2261 case T_zone_45_only:
2263 m_board->m_LegacyDesignSettingsLoaded =
true;
2267 case T_clearance_min:
2269 m_board->m_LegacyDesignSettingsLoaded =
true;
2275 m_board->m_LegacyDesignSettingsLoaded =
true;
2281 m_board->m_LegacyDesignSettingsLoaded =
true;
2287 m_board->m_LegacyDesignSettingsLoaded =
true;
2291 case T_via_min_annulus:
2293 m_board->m_LegacyDesignSettingsLoaded =
true;
2297 case T_via_min_size:
2299 m_board->m_LegacyDesignSettingsLoaded =
true;
2303 case T_through_hole_min:
2305 m_board->m_LegacyDesignSettingsLoaded =
true;
2310 case T_via_min_drill:
2312 m_board->m_LegacyDesignSettingsLoaded =
true;
2316 case T_hole_to_hole_min:
2318 m_board->m_LegacyDesignSettingsLoaded =
true;
2335 m_board->m_LegacyDesignSettingsLoaded =
true;
2342 m_board->m_LegacyDesignSettingsLoaded =
true;
2348 m_board->m_LegacyDesignSettingsLoaded =
true;
2352 case T_uvias_allowed:
2354 m_board->m_LegacyDesignSettingsLoaded =
true;
2358 case T_blind_buried_vias_allowed:
2360 m_board->m_LegacyDesignSettingsLoaded =
true;
2364 case T_uvia_min_size:
2366 m_board->m_LegacyDesignSettingsLoaded =
true;
2370 case T_uvia_min_drill:
2372 m_board->m_LegacyDesignSettingsLoaded =
true;
2376 case T_user_diff_pair:
2386 m_board->m_LegacyDesignSettingsLoaded =
true;
2391 case T_segment_width:
2393 m_board->m_LegacyDesignSettingsLoaded =
true;
2399 m_board->m_LegacyDesignSettingsLoaded =
true;
2403 case T_mod_edge_width:
2405 m_board->m_LegacyDesignSettingsLoaded =
true;
2409 case T_pcb_text_width:
2411 m_board->m_LegacyDesignSettingsLoaded =
true;
2415 case T_mod_text_width:
2417 m_board->m_LegacyDesignSettingsLoaded =
true;
2421 case T_pcb_text_size:
2424 m_board->m_LegacyDesignSettingsLoaded =
true;
2428 case T_mod_text_size:
2431 m_board->m_LegacyDesignSettingsLoaded =
true;
2437 m_board->m_LegacyDesignSettingsLoaded =
true;
2446 m_board->m_LegacyDesignSettingsLoaded =
true;
2455 m_board->m_LegacyDesignSettingsLoaded =
true;
2460 case T_pad_to_mask_clearance:
2465 case T_solder_mask_min_width:
2470 case T_pad_to_paste_clearance:
2475 case T_pad_to_paste_clearance_ratio:
2480 case T_allow_soldermask_bridges_in_footprints:
2523 case T_aux_axis_origin:
2547 case T_visible_elements:
2554 for(
size_t i = 0; i <
sizeof( int ) * CHAR_BIT; i++ )
2555 m_board->m_LegacyVisibleItems.set( i, visible & ( 1u << i ) );
2563 m_board->m_LegacyDesignSettingsLoaded =
true;
2567 case T_filled_areas_thickness:
2573 case T_pcbplotparams:
2579 parser.SyncLineReaderWith( *
this );
2581 plotParams.
Parse( &parser );
2582 SyncLineReaderWith( parser );
2584 m_board->SetPlotOptions( plotParams );
2589 m_board->GetDesignSettings().m_TentViasFront = tent;
2590 m_board->GetDesignSettings().m_TentViasBack = tent;
2595 case T_zone_defaults:
2600 Unexpected( CurText() );
2606 if( !
m_board->GetDesignSettings().m_HasStackup )
2619 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2621 if( token != T_LEFT )
2623 Expecting( T_LEFT );
2634 Unexpected( CurText() );
2641 std::map<PCB_LAYER_ID, ZONE_LAYER_PROPERTIES>& aProperties )
2648 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2650 if( token != T_LEFT )
2652 Expecting( T_LEFT );
2663 case T_hatch_position:
2670 Unexpected( CurText() );
2675 aProperties.emplace( layer, properties );
2683 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2685 if( token != T_LEFT )
2686 Expecting( T_LEFT );
2692 case T_edge_clearance:
2694 m_board->m_LegacyCopperEdgeClearanceLoaded =
true;
2698 case T_copper_line_width:
2703 case T_copper_text_dims:
2707 case T_courtyard_line_width:
2712 case T_edge_cuts_line_width:
2717 case T_silk_line_width:
2722 case T_silk_text_dims:
2726 case T_fab_layers_line_width:
2731 case T_fab_layers_text_dims:
2735 case T_other_layers_line_width:
2740 case T_other_layers_text_dims:
2744 case T_dimension_units:
2750 case T_dimension_precision:
2757 Unexpected( CurText() );
2767 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2769 if( token == T_LEFT )
2789 case T_keep_upright:
2794 Expecting(
"size, thickness, italic or keep_upright" );
2802 wxCHECK_RET( CurTok() == T_net,
2803 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net." ) );
2805 int netCode =
parseInt(
"net number" );
2807 NeedSYMBOLorNUMBER();
2808 wxString
name = FromUTF8();
2833 wxCHECK_RET( CurTok() == T_net_class,
2834 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net class." ) );
2838 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( wxEmptyString );
2841 NeedSYMBOLorNUMBER();
2842 nc->SetName( FromUTF8() );
2844 nc->SetDescription( FromUTF8() );
2846 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2848 if( token != T_LEFT )
2849 Expecting( T_LEFT );
2879 case T_diff_pair_width:
2883 case T_diff_pair_gap:
2889 NeedSYMBOLorNUMBER();
2891 wxString netName = FromUTF8();
2898 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment(
2899 netName, nc->GetName() );
2905 Expecting(
"clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, "
2906 "diff_pair_width, diff_pair_gap or add_net" );
2912 std::shared_ptr<NET_SETTINGS>& netSettings =
m_board->GetDesignSettings().m_NetSettings;
2914 if( netSettings->HasNetclass( nc->GetName() ) )
2919 error.Printf(
_(
"Duplicate NETCLASS name '%s' in file '%s' at line %d, offset %d." ),
2920 nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(),
2924 else if( nc->GetName() == netSettings->GetDefaultNetclass()->GetName() )
2926 netSettings->SetDefaultNetclass( nc );
2930 netSettings->SetNetclass( nc->GetName(), nc );
2937 wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
2938 CurTok() == T_fp_rect || CurTok() == T_fp_line || CurTok() == T_fp_poly ||
2939 CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
2940 CurTok() == T_gr_rect || CurTok() == T_gr_bbox || CurTok() == T_gr_line ||
2941 CurTok() == T_gr_poly || CurTok() == T_gr_vector,
nullptr,
2942 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_SHAPE." ) );
2947 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aParent );
2956 if( token == T_locked )
2958 shape->SetLocked(
true );
2962 if( token != T_LEFT )
2963 Expecting( T_LEFT );
2970 if( token != T_start )
2971 Expecting( T_start );
2975 shape->SetCenter( pt );
2981 if( token != T_end )
2986 shape->SetStart( pt );
2991 if( token != T_angle )
2992 Expecting( T_angle );
2999 VECTOR2I arc_start, arc_mid, arc_end;
3001 if( token != T_start )
3002 Expecting( T_start );
3010 if( token != T_mid )
3019 if( token != T_end )
3026 shape->SetArcGeometry( arc_start, arc_mid, arc_end );
3036 if( token == T_locked )
3038 shape->SetLocked(
true );
3042 if( token != T_LEFT )
3043 Expecting( T_LEFT );
3047 if( token != T_center )
3048 Expecting( T_center );
3052 shape->SetStart( pt );
3058 if( token != T_end )
3063 shape->SetEnd( pt );
3072 if( token == T_locked )
3074 shape->SetLocked(
true );
3078 if( token != T_LEFT )
3079 Expecting( T_LEFT );
3083 if( token != T_pts )
3087 shape->SetBezierC1(
parseXY());
3088 shape->SetBezierC2(
parseXY());
3092 shape->RebuildBezierToSegmentsPointsList(
m_board->GetDesignSettings().m_MaxError );
3094 shape->RebuildBezierToSegmentsPointsList(
ARC_HIGH_DEF );
3105 if( token == T_locked )
3107 shape->SetLocked(
true );
3111 if( token != T_LEFT )
3112 Expecting( T_LEFT );
3116 if( token != T_start )
3117 Expecting( T_start );
3121 shape->SetStart( pt );
3126 if( token != T_end )
3131 shape->SetEnd( pt );
3152 if( token == T_locked )
3154 shape->SetLocked(
true );
3158 if( token != T_LEFT )
3159 Expecting( T_LEFT );
3163 if( token != T_start )
3164 Expecting( T_start );
3168 shape->SetStart( pt );
3173 if( token != T_end )
3178 shape->SetEnd( pt );
3186 shape->SetPolyPoints( {} );
3192 if( token == T_locked )
3194 shape->SetLocked(
true );
3198 if( token != T_LEFT )
3199 Expecting( T_LEFT );
3203 if( token != T_pts )
3206 while( (token = NextTok() ) != T_RIGHT )
3215 Expecting(
"fp_arc, fp_circle, fp_curve, fp_line, fp_poly or fp_rect" );
3219 Expecting(
"gr_arc, gr_circle, gr_curve, gr_vector, gr_line, gr_poly, gr_rect or "
3224 bool foundFill =
false;
3226 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3228 if( token != T_LEFT )
3229 Expecting( T_LEFT );
3249 case T_solder_mask_margin:
3250 shape->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
3267 strokeParser.SyncLineReaderWith( *
this );
3270 SyncLineReaderWith( strokeParser );
3284 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3286 if( token == T_LEFT )
3303 default: Expecting(
"yes, no, solid, none, hatch, reverse_hatch or cross_hatch" );
3324 Expecting(
"layer, width, fill, tstamp, uuid, locked, net, status, "
3325 "or solder_mask_margin" );
3336 shape->SetFilled(
true );
3341 shape->SetFilled(
true );
3347 if( stroke.
GetWidth() <= 0 && !shape->IsAnyFill() )
3352 shape->SetStroke( stroke );
3354 if(
FOOTPRINT* parentFP = shape->GetParentFootprint() )
3356 shape->Rotate( { 0, 0 }, parentFP->GetOrientation() );
3357 shape->Move( parentFP->GetPosition() );
3360 return shape.release();
3366 wxCHECK_MSG( CurTok() == T_image,
nullptr,
3367 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a reference image." ) );
3370 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap = std::make_unique<PCB_REFERENCE_IMAGE>( aParent );
3372 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3374 if( token != T_LEFT )
3375 Expecting( T_LEFT );
3386 bitmap->SetPosition( pos );
3415 data.reserve( 1 << 19 );
3417 while( token != T_RIGHT )
3419 if( !IsSymbol( token ) )
3420 Expecting(
"base64 image data" );
3426 wxMemoryBuffer buffer = wxBase64Decode( data );
3439 bitmap->SetLocked(
locked );
3454 Expecting(
"at, layer, scale, data, locked or uuid" );
3458 return bitmap.release();
3464 wxCHECK_MSG( CurTok() == T_gr_text || CurTok() == T_fp_text,
nullptr,
3465 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXT." ) );
3468 std::unique_ptr<PCB_TEXT>
text;
3470 T token = NextTok();
3475 text = std::unique_ptr<PCB_TEXT>( aBaseText );
3490 text = std::make_unique<PCB_TEXT>( parentFP );
3494 THROW_IO_ERROR( wxString::Format(
_(
"Cannot handle footprint text type %s" ),
3502 text = std::make_unique<PCB_TEXT>( aParent );
3506 if( token == T_locked )
3508 text->SetLocked(
true );
3512 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
3513 Expecting(
"text value" );
3515 wxString value = FromUTF8();
3516 value.Replace( wxT(
"%V" ), wxT(
"${VALUE}" ) );
3517 value.Replace( wxT(
"%R" ), wxT(
"${REFERENCE}" ) );
3518 text->SetText( value );
3536 text->SetVisible(
true );
3539 return text.release();
3546 bool hasAngle =
false;
3548 bool hasPos =
false;
3554 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
3556 if( token == T_LEFT )
3571 if( CurTok() == T_NUMBER )
3579 if( parentFP && CurTok() == T_unlocked )
3596 if( token == T_knockout )
3623 Expecting(
"layer, effects, locked, render_cache, uuid or tstamp" );
3639 Expecting(
"layer, effects, locked, render_cache or tstamp" );
3648 case T_render_cache:
3654 Expecting(
"layer, hide, effects, locked, render_cache or tstamp" );
3656 Expecting(
"layer, effects, locked, render_cache or tstamp" );
3686 wxCHECK_MSG( CurTok() == T_barcode,
nullptr,
3687 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_BARCODE." ) );
3689 std::unique_ptr<PCB_BARCODE> barcode = std::make_unique<PCB_BARCODE>( aParent );
3691 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
3693 if( token != T_LEFT )
3694 Expecting( T_LEFT );
3705 barcode->SetPosition( pos );
3708 if( CurTok() == T_NUMBER )
3724 barcode->SetWidth( w );
3725 barcode->SetHeight( h );
3732 if( NextTok() != T_STRING )
3733 Expecting( T_STRING );
3735 barcode->SetText( FromUTF8() );
3742 barcode->SetTextSize( h );
3750 std::string kind = CurText();
3751 if( kind ==
"code39" )
3753 else if( kind ==
"code128" )
3755 else if( kind ==
"datamatrix" || kind ==
"data_matrix" )
3757 else if( kind ==
"qr" || kind ==
"qrcode" )
3759 else if( kind ==
"microqr" || kind ==
"micro_qr" )
3762 Expecting(
"barcode type" );
3770 std::string ecc = CurText();
3771 if( ecc ==
"L" || ecc ==
"l" )
3773 else if( ecc ==
"M" || ecc ==
"m" )
3775 else if( ecc ==
"Q" || ecc ==
"q" )
3777 else if( ecc ==
"H" || ecc ==
"h" )
3780 Expecting(
"ecc level" );
3798 Expecting(
"at, layer, size, text, text_height, type, ecc_level, locked or uuid" );
3802 barcode->AssembleBarcode();
3804 return barcode.release();
3810 wxCHECK_MSG( CurTok() == T_gr_text_box || CurTok() == T_fp_text_box,
nullptr,
3811 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXTBOX." ) );
3813 std::unique_ptr<PCB_TEXTBOX> textbox = std::make_unique<PCB_TEXTBOX>( aParent );
3817 return textbox.release();
3823 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
3824 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
3826 std::unique_ptr<PCB_TABLECELL> cell = std::make_unique<PCB_TABLECELL>( aParent );
3830 return cell.release();
3841 bool foundMargins =
false;
3843 T token = NextTok();
3846 if( token == T_locked )
3852 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
3853 Expecting(
"text value" );
3855 aTextBox->
SetText( FromUTF8() );
3857 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3859 if( token != T_LEFT )
3860 Expecting( T_LEFT );
3880 if( token != T_end )
3896 while( (token = NextTok() ) != T_RIGHT )
3912 strokeParser.SyncLineReaderWith( *
this );
3915 SyncLineReaderWith( strokeParser );
3930 foundMargins =
true;
3942 Expecting(
"locked, start, pts, angle, width, margins, layer, effects, span, "
3943 "render_cache, uuid or tstamp" );
3956 cell->SetColSpan(
parseInt(
"column span" ) );
3957 cell->SetRowSpan(
parseInt(
"row span" ) );
3961 Expecting(
"locked, start, pts, angle, width, stroke, border, margins, knockout, "
3962 "layer, effects, render_cache, uuid or tstamp" );
3979 case T_render_cache:
3986 Expecting(
"locked, start, pts, angle, width, margins, layer, effects, span, "
3987 "render_cache, uuid or tstamp" );
3991 Expecting(
"locked, start, pts, angle, width, stroke, border, margins, knockout,"
3992 "layer, effects, render_cache, uuid or tstamp" );
4013 aTextBox->
Rotate( { 0, 0 }, parentFP->GetOrientation() );
4014 aTextBox->
Move( parentFP->GetPosition() );
4021 wxCHECK_MSG( CurTok() == T_table,
nullptr,
4022 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
4027 std::unique_ptr<PCB_TABLE>
table = std::make_unique<PCB_TABLE>( aParent, -1 );
4029 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4031 if( token != T_LEFT )
4032 Expecting( T_LEFT );
4038 case T_column_count:
4063 case T_column_widths:
4067 while( ( token = NextTok() ) != T_RIGHT )
4077 while( ( token = NextTok() ) != T_RIGHT )
4084 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4086 if( token != T_LEFT )
4087 Expecting( T_LEFT );
4091 if( token != T_table_cell )
4092 Expecting(
"table_cell" );
4100 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4102 if( token != T_LEFT )
4103 Expecting( T_LEFT );
4122 strokeParser.SyncLineReaderWith( *
this );
4125 SyncLineReaderWith( strokeParser );
4127 table->SetBorderStroke( borderStroke );
4132 Expecting(
"external, header or stroke" );
4140 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4142 if( token != T_LEFT )
4143 Expecting( T_LEFT );
4162 strokeParser.SyncLineReaderWith( *
this );
4165 SyncLineReaderWith( strokeParser );
4167 table->SetSeparatorsStroke( separatorsStroke );
4172 Expecting(
"rows, cols, or stroke" );
4180 Expecting(
"columns, layer, col_widths, row_heights, border, separators, header or "
4185 return table.release();
4191 wxCHECK_MSG( CurTok() == T_dimension,
nullptr,
4192 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as DIMENSION." ) );
4196 std::unique_ptr<PCB_DIMENSION_BASE> dim;
4201 if( token == T_locked )
4208 if( token != T_LEFT )
4213 bool isLegacyDimension =
false;
4214 bool isStyleKnown =
false;
4217 if( token == T_width )
4219 isLegacyDimension =
true;
4220 dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
4226 if( token != T_type )
4227 Expecting( T_type );
4231 case T_aligned: dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
break;
4232 case T_orthogonal: dim = std::make_unique<PCB_DIM_ORTHOGONAL>( aParent );
break;
4233 case T_leader: dim = std::make_unique<PCB_DIM_LEADER>( aParent );
break;
4234 case T_center: dim = std::make_unique<PCB_DIM_CENTER>( aParent );
break;
4235 case T_radial: dim = std::make_unique<PCB_DIM_RADIAL>( aParent );
break;
4236 default: wxFAIL_MSG( wxT(
"Cannot parse unknown dimension type " )
4237 + GetTokenString( CurTok() ) );
4247 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4249 if( token != T_LEFT )
4250 Expecting( T_LEFT );
4275 bool is_aligned = dim->GetKeepTextAligned();
4281 dim->SetKeepTextAligned(
false );
4286 if( isLegacyDimension )
4291 dim->SetAutoUnits(
true );
4293 dim->SetUnits( units );
4298 dim->SetKeepTextAligned( is_aligned );
4299 dim->SetTextPositionMode( t_dim_pos );
4310 dim->SetStart( point );
4312 dim->SetEnd( point );
4332 case T_leader_length:
4348 int orientation =
parseInt(
"orthogonal dimension orientation" );
4354 orientation = std::clamp( orientation, 0, 1 );
4363 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4371 NeedSYMBOLorNUMBER();
4372 dim->SetPrefix( FromUTF8() );
4377 NeedSYMBOLorNUMBER();
4378 dim->SetSuffix( FromUTF8() );
4384 int mode =
parseInt(
"dimension units mode" );
4385 mode = std::max( 0, std::min( 4, mode ) );
4391 case T_units_format:
4393 int format =
parseInt(
"dimension units format" );
4394 format = std::clamp( format, 0, 3 );
4405 case T_override_value:
4406 NeedSYMBOLorNUMBER();
4407 dim->SetOverrideTextEnabled(
true );
4408 dim->SetOverrideText( FromUTF8() );
4412 case T_suppress_zeroes:
4417 std::cerr <<
"Unknown format token: " << GetTokenString( token ) << std::endl;
4418 Expecting(
"prefix, suffix, units, units_format, precision, override_value, "
4419 "suppress_zeroes" );
4427 isStyleKnown =
true;
4430 dim->SetKeepTextAligned(
false );
4432 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4440 dim->SetLineThickness(
parseBoardUnits(
"extension line thickness value" ) );
4444 case T_arrow_direction:
4448 if( token == T_inward )
4450 else if( token == T_outward )
4453 Expecting(
"inward or outward" );
4458 case T_arrow_length:
4464 case T_text_position_mode:
4466 int mode =
parseInt(
"text position mode" );
4467 mode = std::max( 0, std::min( 3, mode ) );
4473 case T_extension_height:
4476 wxCHECK_MSG( aligned,
nullptr, wxT(
"Invalid extension_height token" ) );
4482 case T_extension_offset:
4483 dim->SetExtensionOffset(
parseBoardUnits(
"extension offset value" ) );
4487 case T_keep_text_aligned:
4494 wxT(
"Invalid text_frame token" ) );
4498 int textFrame =
parseInt(
"text frame mode" );
4499 textFrame = std::clamp( textFrame, 0, 3 );
4506 Expecting(
"thickness, arrow_length, arrow_direction, text_position_mode, "
4507 "extension_height, extension_offset" );
4520 if( token != T_pts )
4526 dim->SetStart( point );
4540 if( token != T_pts )
4546 dim->SetEnd( point );
4560 if( token == T_pts )
4582 if( token != T_pts )
4596 if( token != T_pts )
4610 if( token != T_pts )
4624 if( token != T_pts )
4638 dim->SetLocked( isLocked );
4643 Expecting(
"layer, tstamp, uuid, gr_text, feature1, feature2, crossbar, arrow1a, "
4644 "arrow1b, arrow2a, or arrow2b" );
4649 dim->SetLocked(
true );
4653 return dim.release();
4675 wxCHECK_MSG( CurTok() == T_module || CurTok() == T_footprint,
nullptr,
4676 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FOOTPRINT." ) );
4684 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
4686 footprint->SetInitialComments( aInitialComments );
4690 footprint->SetStaticComponentClass(
4691 m_board->GetComponentClassManager().GetNoneComponentClass() );
4696 if( !IsSymbol( token ) && token != T_NUMBER )
4697 Expecting(
"symbol|number" );
4703 THROW_IO_ERROR( wxString::Format(
_(
"Invalid footprint ID in\nfile: %s\nline: %d\n"
4705 CurSource(), CurLineNumber(), CurOffset() ) );
4718 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4720 if( token == T_LEFT )
4730 int this_version =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
4735 footprint->SetFileFormatVersionAtLoad( this_version );
4746 case T_generator_version:
4799 footprint->SetPosition( pt );
4802 if( token == T_NUMBER )
4807 else if( token != T_RIGHT )
4809 Expecting( T_RIGHT );
4815 NeedSYMBOLorNUMBER();
4816 footprint->SetLibDescription( FromUTF8() );
4821 NeedSYMBOLorNUMBER();
4822 footprint->SetKeywords( FromUTF8() );
4829 wxString pName = FromUTF8();
4831 wxString pValue = FromUTF8();
4839 if( pName ==
"ki_keywords" || pName ==
"ki_locked" )
4847 if( pName ==
"ki_description" )
4855 if( pName ==
"Sheetfile" || pName ==
"Sheet file" )
4857 footprint->SetSheetfile( pValue );
4862 if( pName ==
"Sheetname" || pName ==
"Sheet name" )
4864 footprint->SetSheetname( pValue );
4871 std::unique_ptr<PCB_FIELD> unusedField;
4875 if( pName ==
"ki_fp_filters" )
4877 footprint->SetFilters( pValue );
4882 unusedField = std::make_unique<PCB_FIELD>( footprint.get(),
FIELD_T::USER );
4883 field = unusedField.get();
4885 else if( pName ==
"Footprint" )
4891 field = unusedField.get();
4893 else if( footprint->HasField( pName ) )
4895 field = footprint->GetField( pName );
4901 footprint->Add( field );
4922 NeedSYMBOLorNUMBER();
4923 footprint->SetPath(
KIID_PATH( FromUTF8() ) );
4929 footprint->SetSheetname( FromUTF8() );
4935 footprint->SetSheetfile( FromUTF8() );
4941 std::vector<FOOTPRINT::FP_UNIT_INFO> unitInfos;
4944 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4946 if( token == T_LEFT )
4949 if( token == T_unit )
4953 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4955 if( token == T_LEFT )
4958 if( token == T_name )
4960 NeedSYMBOLorNUMBER();
4961 info.m_unitName = FromUTF8();
4964 else if( token == T_pins )
4967 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4969 if( token == T_STRING || token == T_NUMBER )
4971 info.m_pins.emplace_back( FromUTF8() );
4975 Expecting(
"pin number" );
4986 unitInfos.push_back(
info );
4995 if( !unitInfos.empty() )
4996 footprint->SetUnitInfo( unitInfos );
5001 case T_autoplace_cost90:
5002 case T_autoplace_cost180:
5003 parseInt(
"legacy auto-place cost" );
5007 case T_private_layers:
5011 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5016 privateLayers.
set( it->second );
5018 Expecting(
"layer name" );
5027 footprint->SetPrivateLayers( privateLayers );
5031 case T_net_tie_pad_groups:
5032 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5033 footprint->AddNetTiePadGroup( CurStr() );
5037 case T_duplicate_pad_numbers_are_jumpers:
5038 footprint->SetDuplicatePadNumbersAreJumpers(
parseBool() );
5042 case T_jumper_pad_groups:
5045 std::vector<std::set<wxString>>& groups = footprint->JumperPadGroups();
5046 std::set<wxString>* currentGroup =
nullptr;
5048 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
5050 switch(
static_cast<int>( token ) )
5053 currentGroup = &groups.emplace_back();
5058 currentGroup->insert( FromUTF8() );
5063 currentGroup =
nullptr;
5067 Expecting(
"list of pad names" );
5074 case T_solder_mask_margin:
5075 footprint->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
5080 footprint->SetLocalSolderMaskMargin( {} );
5084 case T_solder_paste_margin:
5085 footprint->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
5090 footprint->SetLocalSolderPasteMargin( {} );
5094 case T_solder_paste_ratio:
5095 case T_solder_paste_margin_ratio:
5096 footprint->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
5101 footprint->SetLocalSolderPasteMarginRatio( {} );
5106 footprint->SetLocalClearance(
parseBoardUnits(
"local clearance value" ) );
5111 footprint->SetLocalClearance( {} );
5115 case T_zone_connect:
5120 case T_thermal_width:
5128 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5136 case T_through_hole:
5148 case T_exclude_from_pos_files:
5152 case T_exclude_from_bom:
5156 case T_allow_missing_courtyard:
5157 footprint->SetAllowMissingCourtyard(
true );
5164 case T_allow_soldermask_bridges:
5165 footprint->SetAllowSolderMaskBridges(
true );
5169 Expecting(
"through_hole, smd, virtual, board_only, exclude_from_pos_files, "
5170 "exclude_from_bom or allow_solder_mask_bridges" );
5182 switch( field->GetId() )
5186 const_cast<KIID&
>( footprint->Reference().m_Uuid ) =
text->m_Uuid;
5192 const_cast<KIID&
>( footprint->Value().m_Uuid ) =
text->m_Uuid;
5269 footprint->Add3DModel(
model );
5291 case T_embedded_fonts:
5293 footprint->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
5298 case T_embedded_files:
5301 embeddedFilesParser.SyncLineReaderWith( *
this );
5305 embeddedFilesParser.
ParseEmbedded( footprint->GetEmbeddedFiles() );
5309 wxLogError( e.
What() );
5312 SyncLineReaderWith( embeddedFilesParser );
5316 case T_component_classes:
5318 std::unordered_set<wxString> componentClassNames;
5320 while( ( token = NextTok() ) != T_RIGHT )
5322 if( token != T_LEFT )
5323 Expecting( T_LEFT );
5325 if( ( token = NextTok() ) != T_class )
5326 Expecting( T_class );
5328 NeedSYMBOLorNUMBER();
5329 componentClassNames.insert(
From_UTF8( CurText() ) );
5333 footprint->SetTransientComponentClassNames( componentClassNames );
5336 footprint->ResolveComponentClassNames(
m_board, componentClassNames );
5342 Expecting(
"at, descr, locked, placed, tedit, tstamp, uuid, "
5343 "autoplace_cost90, autoplace_cost180, attr, clearance, "
5344 "embedded_files, fp_arc, fp_circle, fp_curve, fp_line, fp_poly, "
5345 "fp_rect, fp_text, pad, group, generator, model, path, solder_mask_margin, "
5346 "solder_paste_margin, solder_paste_margin_ratio, tags, thermal_gap, "
5347 "version, zone, zone_connect, or component_classes" );
5351 footprint->FixUpPadsForBoard(
m_board );
5363 if( footprint->GetKeywords().StartsWith( wxT(
"net tie" ) ) )
5367 for(
PAD*
pad : footprint->Pads() )
5369 if( !padGroup.IsEmpty() )
5370 padGroup += wxS(
", " );
5372 padGroup +=
pad->GetNumber();
5375 if( !padGroup.IsEmpty() )
5376 footprint->AddNetTiePadGroup( padGroup );
5380 footprint->SetAttributes( attributes );
5382 footprint->SetFPID( fpid );
5384 return footprint.release();
5390 wxCHECK_RET( CurTok() == T_stackup,
"Expected stackup token" );
5396 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
5398 if( CurTok() != T_LEFT )
5399 Expecting( T_LEFT );
5407 NeedSYMBOLorNUMBER();
5412 Expecting(
"layer name" );
5416 layers.
set( it->second );
5424 Expecting(
"layer" );
5434 if( gotCuLayers.count() % 2 != 0 )
5437 "odd number of copper layers (%d)." ),
5438 gotCuLayers.count() ) );
5442 if( gotCuLayers != expectedCuLayers )
5445 "copper layers are not contiguous." ) ) );
5451 "technology layers are implicit in footprints and "
5452 "should not be specified in the stackup." ) ) );
5463 wxCHECK_MSG( CurTok() == T_pad,
nullptr,
5464 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PAD." ) );
5468 bool foundNet =
false;
5469 bool foundNetcode =
false;
5471 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
5473 NeedSYMBOLorNUMBER();
5474 pad->SetNumber( FromUTF8() );
5476 T token = NextTok();
5505 case T_np_thru_hole:
5510 Expecting(
"thru_hole, smd, connect, or np_thru_hole" );
5544 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
5547 std::optional<EDA_ANGLE> thermalBrAngleOverride;
5549 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5551 if( token == T_locked )
5557 if( token != T_LEFT )
5558 Expecting( T_LEFT );
5574 pad->SetFPRelativePosition( pt );
5577 if( token == T_NUMBER )
5582 else if( token != T_RIGHT )
5584 Expecting(
") or angle value" );
5601 bool haveWidth =
false;
5604 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5606 if( token == T_LEFT )
5620 drillSize.
y = drillSize.
x;
5639 Expecting(
"oval, size, or offset" );
5648 pad->SetDrillSize( drillSize );
5660 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5662 if( token != T_LEFT )
5663 Expecting( T_LEFT );
5688 Expecting(
"size or layers" );
5695 case T_tertiary_drill:
5700 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5702 if( token != T_LEFT )
5703 Expecting( T_LEFT );
5728 Expecting(
"size or layers" );
5739 pad->SetLayerSet( layerMask );
5754 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d offset: %d" ),
5755 CurSource(), CurLineNumber(), CurOffset() );
5758 foundNetcode =
true;
5762 if( !IsSymbol( token ) )
5764 Expecting(
"net name" );
5770 wxString netName( FromUTF8() );
5779 if( netName !=
m_board->FindNet(
pad->GetNetCode() )->GetNetname() )
5782 wxLogError(
_(
"Net name doesn't match ID in\nfile: %s\nline: %d offset: %d" ),
5783 CurSource(), CurLineNumber(), CurOffset() );
5796 pad->SetNet( netinfo );
5804 NeedSYMBOLorNUMBER();
5805 pad->SetPinFunction( FromUTF8() );
5810 NeedSYMBOLorNUMBER();
5811 pad->SetPinType( FromUTF8() );
5831 case T_solder_mask_margin:
5832 pad->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
5837 pad->SetLocalSolderMaskMargin( {} );
5841 case T_solder_paste_margin:
5842 pad->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
5847 pad->SetLocalSolderPasteMargin( {} );
5851 case T_solder_paste_margin_ratio:
5852 pad->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
5857 pad->SetLocalSolderPasteMarginRatio( {} );
5867 pad->SetLocalClearance( {} );
5875 case T_zone_connect:
5880 case T_thermal_width:
5881 case T_thermal_bridge_width:
5886 case T_thermal_bridge_angle:
5897 case T_roundrect_rratio:
5903 case T_chamfer_ratio:
5915 bool end_list =
false;
5935 case T_bottom_right:
5945 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
5946 "chamfer_bottom_right" );
5957 while( token != T_RIGHT )
5972 case T_RIGHT:
break;
5976 Expecting(
"pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc"
5977 " pad_prop_heatsink or pad_prop_castellated" );
5994 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5996 if( token == T_LEFT )
6027 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
6034 case T_remove_unused_layers:
6037 pad->SetRemoveUnconnected( remove );
6041 case T_keep_end_layers:
6044 pad->SetKeepTopBottom( keep );
6051 pad->Padstack().FrontOuterLayers().has_solder_mask = front;
6052 pad->Padstack().BackOuterLayers().has_solder_mask = back;
6056 case T_zone_layer_connections:
6063 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6068 Expecting(
"copper layer name" );
6089 case T_front_post_machining:
6093 case T_back_post_machining:
6098 Expecting(
"at, locked, drill, layers, net, die_length, roundrect_rratio, "
6099 "solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, uuid, "
6100 "clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
6101 "pinfunction, pintype, zone_connect, thermal_width, thermal_gap, padstack, "
6102 "teardrops, front_post_machining, or back_post_machining" );
6109 pad->SetNetCode( 0,
true );
6112 if( thermalBrAngleOverride )
6114 pad->SetThermalSpokeAngle( *thermalBrAngleOverride );
6137 if( !
pad->CanHaveNumber() )
6141 pad->SetNumber( wxEmptyString );
6145 if(
pad->GetSizeX() <= 0 ||
pad->GetSizeY() <= 0 )
6150 wxLogWarning(
_(
"Invalid zero-sized pad pinned to %s in\nfile: %s\nline: %d\noffset: %d" ),
6151 wxT(
"1µm" ), CurSource(), CurLineNumber(), CurOffset() );
6154 return pad.release();
6161 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
6163 if( token != T_LEFT )
6164 Expecting( T_LEFT );
6185 Expecting(
"circle or rect" );
6206 Expecting(
"outline or convexhull" );
6214 Expecting(
"anchor or clearance" );
6228 T token = NextTok();
6241 Expecting(
"counterbore or countersink" );
6245 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6247 if( token != T_LEFT )
6248 Expecting( T_LEFT );
6270 Expecting(
"size, depth, or angle" );
6280 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
6282 if( token != T_LEFT )
6283 Expecting( T_LEFT );
6294 case T_front_inner_back:
6303 Expecting(
"front_inner_back or custom" );
6314 if( curText ==
"Inner" )
6318 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
6319 "line: %d\noffset: %d." ),
6320 CurSource(), CurLineNumber(), CurOffset() ) );
6333 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
6334 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
6342 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6344 if( token != T_LEFT )
6345 Expecting( T_LEFT );
6383 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
6394 aPad->
SetSize( curLayer, sz );
6419 case T_roundrect_rratio:
6424 case T_chamfer_ratio:
6439 bool end_list =
false;
6459 case T_bottom_right:
6469 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
6470 "chamfer_bottom_right" );
6480 case T_thermal_bridge_width:
6490 case T_thermal_bridge_angle:
6495 case T_zone_connect:
6497 magic_enum::enum_cast<ZONE_CONNECTION>(
parseInt(
"zone connection value" ) );
6517 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6519 if( token != T_LEFT )
6520 Expecting( T_LEFT );
6559 while( ( token = NextTok() ) != T_RIGHT )
6572 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6574 if( token == T_LEFT )
6605 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
6622 Expecting(
"mode or layer" );
6633 while( ( token = NextTok() ) != T_RIGHT )
6638 KIID uuid( CurStr() );
6646 wxCHECK_RET( CurTok() == T_group,
6647 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
6653 groupInfo.
parent = aParent;
6655 while( ( token = NextTok() ) != T_LEFT )
6657 if( token == T_STRING )
6658 groupInfo.
name = FromUTF8();
6659 else if( token == T_locked )
6662 Expecting(
"group name or locked" );
6665 for( ; token != T_RIGHT; token = NextTok() )
6667 if( token != T_LEFT )
6668 Expecting( T_LEFT );
6686 if( !IsSymbol( token ) && token != T_NUMBER )
6687 Expecting(
"symbol|number" );
6689 wxString
name = FromUTF8();
6693 name.Replace(
"{slash}",
"/" );
6699 if(
static_cast<int>(
name.size() ) > bad_pos )
6701 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
6708 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
6725 Expecting(
"uuid, locked, lib_id, or members" );
6733 wxCHECK_RET( CurTok() == T_generated,
6734 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GENERATOR." ) );
6742 genInfo.
parent = aParent;
6749 if( token != T_uuid && token != T_id )
6750 Expecting( T_uuid );
6756 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6758 if( token != T_LEFT )
6759 Expecting( T_LEFT );
6773 genInfo.
name = FromUTF8();
6779 genInfo.
locked = token == T_yes;
6794 wxString pName = FromUTF8();
6800 genInfo.
properties.emplace( pName, wxAny(
true ) );
6805 genInfo.
properties.emplace( pName, wxAny(
false ) );
6812 genInfo.
properties.emplace( pName, wxAny( pValue ) );
6819 wxString pValue = FromUTF8();
6839 genInfo.
properties.emplace( pName, wxAny( pt ) );
6849 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6858 Expecting(
"xy or pts" );
6865 Expecting(
"a number, symbol, string or (" );
6881 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
6882 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ARC." ) );
6887 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board );
6889 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6892 if( token == T_locked )
6894 arc->SetLocked(
true );
6898 if( token != T_LEFT )
6899 Expecting( T_LEFT );
6908 arc->SetStart( pt );
6940 case T_solder_mask_margin:
6941 arc->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6967 Expecting(
"start, mid, end, width, layer, solder_mask_margin, net, tstamp, uuid or status" );
6977 return arc.release();
6983 wxCHECK_MSG( CurTok() == T_segment,
nullptr,
6984 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TRACK." ) );
6989 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
6991 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6994 if( token == T_locked )
6996 track->SetLocked(
true );
7000 if( token != T_LEFT )
7001 Expecting( T_LEFT );
7010 track->SetStart( pt );
7017 track->SetEnd( pt );
7035 case T_solder_mask_margin:
7036 track->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
7062 Expecting(
"start, end, width, layer, solder_mask_margin, net, tstamp, uuid or locked" );
7072 return track.release();
7078 wxCHECK_MSG( CurTok() == T_via,
nullptr,
7079 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_VIA." ) );
7084 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
7093 via->Padstack().FrontOuterLayers().has_covering =
false;
7094 via->Padstack().BackOuterLayers().has_covering =
false;
7095 via->Padstack().FrontOuterLayers().has_plugging =
false;
7096 via->Padstack().BackOuterLayers().has_plugging =
false;
7097 via->Padstack().Drill().is_filled =
false;
7098 via->Padstack().Drill().is_capped =
false;
7101 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7104 if( token == T_locked )
7106 via->SetLocked(
true );
7110 if( token == T_LEFT )
7130 via->SetStart( pt );
7152 via->SetLayerPair( layer1, layer2 );
7155 Expecting(
"layer name" );
7165 case T_remove_unused_layers:
7167 via->SetRemoveUnconnected(
true );
7171 case T_keep_end_layers:
7173 via->SetKeepStartEnd(
true );
7177 case T_start_end_only:
7183 case T_zone_layer_connections:
7191 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7196 Expecting(
"copper layer name" );
7215 via->Padstack().FrontOuterLayers().has_solder_mask = front;
7216 via->Padstack().BackOuterLayers().has_solder_mask = back;
7223 via->Padstack().FrontOuterLayers().has_covering = front;
7224 via->Padstack().BackOuterLayers().has_covering = back;
7231 via->Padstack().FrontOuterLayers().has_plugging = front;
7232 via->Padstack().BackOuterLayers().has_plugging = back;
7272 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7274 if( token != T_LEFT )
7275 Expecting( T_LEFT );
7300 Expecting(
"size or layers" );
7307 case T_tertiary_drill:
7312 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7314 if( token != T_LEFT )
7315 Expecting( T_LEFT );
7340 Expecting(
"size or layers" );
7347 case T_front_post_machining:
7351 case T_back_post_machining:
7356 Expecting(
"blind, micro, at, size, drill, layers, net, free, tstamp, uuid, status, "
7357 "teardrops, backdrill, tertiary_drill, front_post_machining, or "
7358 "back_post_machining" );
7362 return via.release();
7366std::pair<std::optional<bool>, std::optional<bool>>
7369 T token = NextTok();
7371 std::optional<bool> front( std::nullopt );
7372 std::optional<bool> back( std::nullopt );
7374 if( token != T_LEFT && aAllowLegacyFormat )
7377 while( token != T_RIGHT )
7379 if( token == T_front )
7383 else if( token == T_back )
7387 else if( token == T_none )
7394 Expecting(
"front, back or none" );
7400 return { front, back };
7403 while( token != T_RIGHT )
7405 if( token != T_LEFT )
7410 if( token == T_front )
7412 else if( token == T_back )
7415 Expecting(
"front or back" );
7422 return { front, back };
7430 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
7432 if( token != T_LEFT )
7433 Expecting( T_LEFT );
7444 case T_front_inner_back:
7453 Expecting(
"front_inner_back or custom" );
7464 if( curText ==
"Inner" )
7468 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
7469 "line: %d\noffset: %d." ),
7470 CurSource(), CurLineNumber(), CurOffset() ) );
7483 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
7484 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
7488 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7490 if( token != T_LEFT )
7491 Expecting( T_LEFT );
7501 padstack.
SetSize( { diameter, diameter }, curLayer );
7508 Expecting(
"size" );
7516 Expecting(
"mode or layer" );
7525 wxCHECK_MSG( CurTok() == T_zone,
nullptr,
7526 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ZONE." ) );
7533 wxString legacyNetnameFromFile;
7536 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
7537 std::map<PCB_LAYER_ID, std::vector<SEG>> legacySegs;
7539 bool addedFilledPolygons =
false;
7545 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aParent );
7547 zone->SetAssignedPriority( 0 );
7552 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7555 if( token == T_locked )
7557 zone->SetLocked(
true );
7561 if( token == T_LEFT )
7571 NeedSYMBOLorNUMBER();
7572 legacyNetnameFromFile = FromUTF8();
7599 if( token != T_none && token != T_edge && token != T_full )
7600 Expecting(
"none, edge, or full" );
7615 zone->SetAssignedPriority(
parseInt(
"zone priority" ) );
7619 case T_connect_pads:
7620 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7622 if( token == T_LEFT )
7635 case T_thru_hole_only:
7645 Expecting(
"yes, no, or clearance" );
7651 case T_min_thickness:
7656 case T_filled_areas_thickness:
7663 isStrokedFill =
false;
7669 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7671 if( token == T_LEFT )
7677 zone->SetIsFilled(
true );
7683 if( token != T_segment && token != T_hatch && token != T_polygon )
7684 Expecting(
"segment, hatch or polygon" );
7702 case T_hatch_thickness:
7712 case T_hatch_orientation:
7715 zone->SetHatchOrientation( orientation );
7720 case T_hatch_smoothing_level:
7721 zone->SetHatchSmoothingLevel(
parseDouble( T_hatch_smoothing_level ) );
7725 case T_hatch_smoothing_value:
7726 zone->SetHatchSmoothingValue(
parseDouble( T_hatch_smoothing_value ) );
7730 case T_hatch_border_algorithm:
7733 if( token != T_hatch_thickness && token != T_min_thickness )
7734 Expecting(
"hatch_thickness or min_thickness" );
7736 zone->SetHatchBorderAlgorithm( token == T_hatch_thickness ? 1 : 0 );
7740 case T_hatch_min_hole_area:
7741 zone->SetHatchHoleMinArea(
parseDouble( T_hatch_min_hole_area ) );
7745 case T_arc_segments:
7755 case T_thermal_bridge_width:
7756 zone->SetThermalReliefSpokeWidth(
parseBoardUnits( T_thermal_bridge_width ) );
7768 if( !zone->GetIsRuleArea() )
7774 if( !zone->GetIsRuleArea() )
7780 Expecting(
"none, chamfer, or fillet" );
7789 if( !zone->GetIsRuleArea() )
7790 zone->SetCornerRadius( tmp );
7795 case T_island_removal_mode:
7796 tmp =
parseInt(
"island_removal_mode" );
7798 if( tmp >= 0 && tmp <= 2 )
7804 case T_island_area_min:
7807 zone->SetMinIslandArea( area *
pcbIUScale.IU_PER_MM );
7813 Expecting(
"mode, arc_segments, thermal_gap, thermal_bridge_width, "
7814 "hatch_thickness, hatch_gap, hatch_orientation, "
7815 "hatch_smoothing_level, hatch_smoothing_value, "
7816 "hatch_border_algorithm, hatch_min_hole_area, smoothing, radius, "
7817 "island_removal_mode, or island_area_min" );
7824 zone->SetIsRuleArea(
true );
7826 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7828 if( token == T_LEFT )
7837 zone->SetPlacementAreaSource( FromUTF8() );
7840 case T_component_class:
7844 zone->SetPlacementAreaSource( FromUTF8() );
7851 zone->SetPlacementAreaSource( FromUTF8() );
7858 if( token == T_yes )
7859 zone->SetPlacementAreaEnabled(
true );
7860 else if( token == T_no )
7861 zone->SetPlacementAreaEnabled(
false );
7863 Expecting(
"yes or no" );
7869 Expecting(
"enabled, sheetname, component_class, or group" );
7881 zone->SetIsRuleArea(
true );
7884 zone->SetDoNotAllowPads(
false );
7885 zone->SetDoNotAllowFootprints(
false );
7887 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7889 if( token == T_LEFT )
7897 if( token != T_allowed && token != T_not_allowed )
7898 Expecting(
"allowed or not_allowed" );
7900 zone->SetDoNotAllowTracks( token == T_not_allowed );
7906 if( token != T_allowed && token != T_not_allowed )
7907 Expecting(
"allowed or not_allowed" );
7909 zone->SetDoNotAllowVias( token == T_not_allowed );
7915 if( token != T_allowed && token != T_not_allowed )
7916 Expecting(
"allowed or not_allowed" );
7918 zone->SetDoNotAllowZoneFills( token == T_not_allowed );
7924 if( token != T_allowed && token != T_not_allowed )
7925 Expecting(
"allowed or not_allowed" );
7927 zone->SetDoNotAllowPads( token == T_not_allowed );
7933 if( token != T_allowed && token != T_not_allowed )
7934 Expecting(
"allowed or not_allowed" );
7936 zone->SetDoNotAllowFootprints( token == T_not_allowed );
7940 Expecting(
"tracks, vias or copperpour" );
7955 if( token != T_pts )
7958 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7967 zone->AddPolygon( outline );
7971 case T_filled_polygon:
7977 if( token == T_layer )
7983 if( token != T_LEFT )
7984 Expecting( T_LEFT );
7991 filledLayer = zone->GetFirstLayer();
7994 bool island =
false;
7996 if( token == T_island )
8003 if( token != T_pts )
8006 if( !pts.count( filledLayer ) )
8015 zone->SetIsIsland( filledLayer, idx );
8017 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8022 addedFilledPolygons |= !poly.
IsEmpty();
8027 case T_fill_segments:
8031 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8033 if( token != T_LEFT )
8034 Expecting( T_LEFT );
8038 if( token != T_pts )
8042 filledLayer = zone->GetFirstLayer();
8049 legacySegs[filledLayer].push_back( fillSegment );
8059 zone->SetZoneName( FromUTF8() );
8064 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8066 if( token == T_LEFT )
8072 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8074 if( token == T_LEFT )
8082 if( token == T_padvia )
8084 else if( token == T_track_end )
8087 Expecting(
"padvia or track_end" );
8093 Expecting(
"type" );
8100 Expecting(
"teardrop" );
8111 Expecting(
"net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
8112 "fill, polygon, filled_polygon, fill_segments, attr, locked, uuid, or name" );
8116 if( zone->GetNumCorners() > 2 )
8118 if( !zone->IsOnCopperLayer() )
8125 zone->SetBorderDisplayStyle( hatchStyle, hatchPitch,
true );
8128 if( addedFilledPolygons )
8130 if( isStrokedFill && !zone->GetIsRuleArea() )
8134 wxLogWarning(
_(
"Legacy zone fill strategy is not supported anymore.\n"
8135 "Zone fills will be converted on best-effort basis." ) );
8140 if( zone->GetMinThickness() > 0 )
8142 for(
auto& [layer, polyset] : pts )
8144 polyset.InflateWithLinkedHoles( zone->GetMinThickness() / 2,
8151 for(
auto& [layer, polyset] : pts )
8152 zone->SetFilledPolysList( layer, polyset );
8154 zone->CalculateFilledArea();
8156 else if( legacySegs.size() > 0 )
8164 wxLogWarning(
_(
"The legacy segment zone fill mode is no longer supported.\n"
8165 "Zone fills will be converted on a best-effort basis." ) );
8171 for(
const auto& [layer, segments] : legacySegs )
8175 if( zone->HasFilledPolysForLayer( layer ) )
8178 for(
const auto& seg : segments )
8189 zone->SetFilledPolysList( layer, layerFill );
8190 zone->CalculateFilledArea();
8198 bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsRuleArea();
8204 if( !legacyNetnameFromFile.IsEmpty() && zone->GetNetname() != legacyNetnameFromFile )
8217 int newnetcode =
m_board->GetNetCount();
8230 m_board->SetLegacyTeardrops(
true );
8233 zone->SetNeedRefill(
false );
8235 return zone.release();
8241 wxCHECK_MSG( CurTok() == T_point,
nullptr,
8242 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_POINT." ) );
8244 std::unique_ptr<PCB_POINT> point = std::make_unique<PCB_POINT>(
nullptr );
8246 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
8248 if( token == T_LEFT )
8258 point->SetPosition( pt );
8281 default: Expecting(
"at, size, layer or uuid" );
8285 return point.release();
8291 wxCHECK_MSG( CurTok() == T_target,
nullptr,
8292 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TARGET." ) );
8297 std::unique_ptr<PCB_TARGET> target = std::make_unique<PCB_TARGET>(
nullptr );
8299 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8301 if( token == T_LEFT )
8307 target->SetShape( 1 );
8311 target->SetShape( 0 );
8317 target->SetPosition( pt );
8344 Expecting(
"x, plus, at, size, width, layer, uuid, or tstamp" );
8348 return target.release();
8355 std::string idStr( CurStr() );
8358 if( *idStr.begin() ==
'"' && *idStr.rbegin() ==
'"' )
8359 idStr = idStr.substr( 1, idStr.length() - 1 );
8368 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.
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)
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.
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
@ 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