34#include <fmt/format.h>
42#include <magic_enum.hpp>
80#include <wx/mstream.h>
89constexpr double INT_LIMIT = std::numeric_limits<int>::max() - 10;
91using namespace PCB_KEYS_T;
131 for(
int i=1; i<=14; ++i )
133 std::string key =
StrPrintf(
"Inner%d.Cu", i );
144 TIME_PT curTime = CLOCK::now();
145 unsigned curLine = reader->LineNumber();
148 if(
delta > std::chrono::milliseconds( 250 ) )
167 while( ( token = NextTok() ) != T_EOF )
169 if( token == T_LEFT )
172 if( token == T_RIGHT )
189 m_netCodes.resize(
static_cast<std::size_t
>( aIndex ) + 1 );
229 else if( token == T_no )
232 Expecting(
"yes or no" );
243 bool ret = aDefaultValue;
245 if( PrevTok() == T_LEFT )
250 if(
static_cast<int>( token ) ==
DSN_RIGHT )
251 return aDefaultValue;
253 if( token == T_yes || token == T_true )
255 else if( token == T_no || token == T_false )
258 Expecting(
"yes or no" );
265 return aDefaultValue;
274 int year, month, day;
283 if( day <= 0 || month <= 0 || month > 12 ||
284 day > wxDateTime::GetNumberOfDays( (wxDateTime::Month)( month - 1 ), year ) )
291 wxDateTime date( day, (wxDateTime::Month)( month - 1 ), year, 0, 0, 0, 0 );
292 return date.FormatDate();
298 if( CurTok() != T_LEFT )
318 if( CurTok() != T_LEFT )
337 bool has_start =
false;
338 bool has_mid =
false;
339 bool has_end =
false;
341 VECTOR2I arc_start, arc_mid, arc_end;
343 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
345 if( token != T_LEFT )
371 Expecting(
"start, mid or end" );
378 Expecting(
"start" );
386 SHAPE_ARC arc( arc_start, arc_mid, arc_end, 0 );
390 if( token != T_RIGHT )
391 Expecting( T_RIGHT );
396 Expecting(
"xy or arc" );
433 return { pName, pValue };
443 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
445 if( token == T_LEFT )
454 case T_allow_two_segments:
458 case T_prefer_zone_connections:
462 case T_best_length_ratio:
472 case T_best_width_ratio:
493 Expecting(
"enabled, allow_two_segments, prefer_zone_connections, best_length_ratio, "
494 "max_length, best_width_ratio, max_width, curve_points or filter_ratio" );
502 wxCHECK_RET( CurTok() == T_effects,
503 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as EDA_TEXT." ) );
521 bool foundTextSize =
false;
524 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
526 if( token == T_LEFT )
532 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
534 if( token == T_LEFT )
541 faceName = FromUTF8();
553 foundTextSize =
true;
582 Expecting(
"face, size, line_spacing, thickness, bold, or italic" );
586 if( !faceName.IsEmpty() )
594 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
596 if( token == T_LEFT )
622 Expecting(
"left, right, top, bottom, or mirror" );
634 Expecting(
"font, justify, or hide" );
653 NeedSYMBOLorNUMBER();
654 wxString cacheText =
From_UTF8( CurText() );
657 text->SetupRenderCache( cacheText,
text->GetFont(), cacheAngle, { 0, 0 } );
659 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
661 if( token != T_LEFT )
666 if( token != T_polygon )
667 Expecting( T_polygon );
671 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
673 if( token != T_LEFT )
683 while( (token = NextTok() ) != T_RIGHT )
694 text->AddRenderCacheGlyph( poly );
701 wxCHECK_MSG( CurTok() == T_model,
nullptr,
702 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FP_3DMODEL." ) );
707 NeedSYMBOLorNUMBER();
710 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
712 if( token == T_LEFT )
799 Expecting(
"at, hide, opacity, offset, scale, or rotate" );
818 if( CurTok() != T_LEFT )
821 if( NextTok() != T_kicad_pcb)
839 std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
846 if( token != T_LEFT )
868 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
879 std::get<2>( params ),
908 std::map<wxString, wxString> properties;
922 std::vector<BOARD_ITEM*> bulkAddedItems;
925 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
929 if( token != T_LEFT )
956 case T_generator_version:
1012 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1013 bulkAddedItems.push_back( item );
1018 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1019 bulkAddedItems.push_back( item );
1024 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1025 bulkAddedItems.push_back( item );
1030 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1031 bulkAddedItems.push_back( item );
1036 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1037 bulkAddedItems.push_back( item );
1042 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1043 bulkAddedItems.push_back( item );
1049 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1050 bulkAddedItems.push_back( item );
1055 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1056 bulkAddedItems.push_back( item );
1061 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1062 bulkAddedItems.push_back( item );
1075 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1076 bulkAddedItems.push_back( item );
1081 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1082 bulkAddedItems.push_back( item );
1087 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
1088 bulkAddedItems.push_back( item );
1091 case T_embedded_fonts:
1098 case T_embedded_files:
1101 embeddedFilesParser.SyncLineReaderWith( *
this );
1109 wxLogError( e.
What() );
1112 SyncLineReaderWith( embeddedFilesParser );
1118 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
1123 if( bulkAddedItems.size() > 0 )
1131 wxString msg, undefinedLayerNames, destLayerName;
1135 if( !undefinedLayerNames.IsEmpty() )
1136 undefinedLayerNames += wxT(
", " );
1138 undefinedLayerNames += layerName;
1145 msg.Printf(
_(
"Items found on undefined layers (%s).\n"
1146 "Do you wish to rescue them to the %s layer?\n"
1148 "Zones will need to be refilled." ),
1149 undefinedLayerNames, destLayerName );
1160 const auto visitItem = [&](
BOARD_ITEM& curr_item )
1162 LSET layers = curr_item.GetLayerSet();
1164 if( layers.test(
Rescue ) )
1166 layers.
set( destLayer );
1170 curr_item.SetLayerSet( layers );
1180 if(
via->GetViaType() == VIATYPE::THROUGH )
1183 via->LayerPair( &top_layer, &bottom_layer );
1187 if( top_layer ==
Rescue )
1190 if( bottom_layer ==
Rescue )
1191 bottom_layer =
B_Cu;
1193 via->SetLayerPair( top_layer, bottom_layer );
1198 visitItem( *track );
1206 visitItem( *drawing );
1210 for(
BOARD_ITEM* drawing : fp->GraphicalItems() )
1211 visitItem( *drawing );
1221 THROW_IO_ERROR( wxT(
"One or more undefined undefinedLayerNames was found; "
1222 "open the board in the PCB Editor to resolve." ) );
1232 ZONE* z =
static_cast<ZONE*
>( zone );
1248 [&](
const KIID& aId )
1252 if(
BOARD* board =
dynamic_cast<BOARD*
>( aParent ) )
1254 aItem = board->GetItem( aId );
1261 if( child->
m_Uuid == aId )
1274 std::vector<const GROUP_INFO*> groupTypeObjects;
1277 groupTypeObjects.emplace_back( &groupInfo );
1280 groupTypeObjects.emplace_back( &genInfo );
1282 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1296 _(
"Cannot create generated object of type '%s'" ), genInfo->genType ) );
1305 group->SetName( groupInfo->name );
1308 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo->uuid;
1310 if( groupInfo->locked )
1311 group->SetLocked(
true );
1314 static_cast<FOOTPRINT*
>( groupInfo->parent )->
Add(
group, ADD_MODE::INSERT,
true );
1316 static_cast<BOARD*
>( groupInfo->parent )->Add(
group, ADD_MODE::INSERT,
true );
1321 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1325 for(
const KIID& aUuid : groupInfo->memberUuids )
1332 item = getItem( aUuid );
1344 group->AddItem( item );
1357 wxCHECK_RET( CurTok() == T_kicad_pcb,
1358 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
1364 if( tok == T_version )
1383 wxCHECK_RET( CurTok() == T_general,
1384 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) +
1385 wxT(
" as a general section." ) );
1389 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1391 if( token != T_LEFT )
1392 Expecting( T_LEFT );
1403 case T_legacy_teardrops:
1408 while( ( token = NextTok() ) != T_RIGHT )
1410 if( !IsSymbol( token ) && token != T_NUMBER )
1411 Expecting(
"symbol or number" );
1420 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200119 ) || CurTok() == T_paper,
1421 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
1428 wxString pageType = FromUTF8();
1430 if( !pageInfo.
SetType( pageType ) )
1433 err.Printf(
_(
"Page type '%s' is not valid." ), FromUTF8() );
1460 if( token == T_portrait )
1465 else if( token != T_RIGHT )
1467 Expecting(
"portrait|)" );
1476 wxCHECK_RET( CurTok() == T_title_block,
1477 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as TITLE_BLOCK." ) );
1482 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1484 if( token != T_LEFT )
1485 Expecting( T_LEFT );
1498 titleBlock.
SetDate( FromUTF8() );
1513 int commentNumber =
parseInt(
"comment" );
1515 switch( commentNumber )
1564 err.Printf( wxT(
"%d is not a valid title block comment number" ), commentNumber );
1572 Expecting(
"title, date, rev, company, or comment" );
1587 std::string userName;
1589 bool isVisible =
true;
1593 if( CurTok() != T_LEFT )
1594 Expecting( T_LEFT );
1597 int layer_num =
parseInt(
"layer index" );
1599 NeedSYMBOLorNUMBER();
1608 if( token == T_hide )
1613 else if( token == T_STRING )
1615 userName = CurText();
1618 else if( token != T_RIGHT )
1620 Expecting(
"hide, user defined name, or )" );
1628 if( !userName.empty() )
1643 int dielectric_idx = 1;
1646 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1648 if( CurTok() != T_LEFT )
1649 Expecting( T_LEFT );
1653 if( token != T_layer )
1657 case T_copper_finish:
1663 case T_edge_plating:
1669 case T_dielectric_constraints:
1675 case T_edge_connector:
1679 if( token == T_yes )
1681 else if( token == T_bevelled )
1687 case T_castellated_pads:
1721 else if( !( layerId & 1 ) )
1734 stackup.
Add( item );
1738 Expecting(
"layer_name" );
1741 bool has_next_sublayer =
true;
1742 int sublayer_idx = 0;
1745 while( has_next_sublayer )
1747 has_next_sublayer =
false;
1749 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1751 if( token == T_addsublayer )
1753 has_next_sublayer =
true;
1757 if( token == T_LEFT )
1773 if( token == T_LEFT )
1776 if( token == T_locked )
1799 case T_loss_tangent:
1819 wxColour wx_color =
color.ToColour();
1822 name.Printf( wxT(
"#%02X%02X%02X%02X" ),
1842 if( has_next_sublayer )
1850 if( token != T_RIGHT )
1867 aMap[
"Adesivo.Retro"] =
"B.Adhes";
1868 aMap[
"Adesivo.Fronte"] =
"F.Adhes";
1869 aMap[
"Pasta.Retro"] =
"B.Paste";
1870 aMap[
"Pasta.Fronte"] =
"F.Paste";
1871 aMap[
"Serigrafia.Retro"] =
"B.SilkS";
1872 aMap[
"Serigrafia.Fronte"] =
"F.SilkS";
1873 aMap[
"Maschera.Retro"] =
"B.Mask";
1874 aMap[
"Maschera.Fronte"] =
"F.Mask";
1875 aMap[
"Grafica"] =
"Dwgs.User";
1876 aMap[
"Commenti"] =
"Cmts.User";
1877 aMap[
"Eco1"] =
"Eco1.User";
1878 aMap[
"Eco2"] =
"Eco2.User";
1879 aMap[
"Contorno.scheda"] =
"Edge.Cuts";
1882 aMap[
"Kleju_Dolna"] =
"B.Adhes";
1883 aMap[
"Kleju_Gorna"] =
"F.Adhes";
1884 aMap[
"Pasty_Dolna"] =
"B.Paste";
1885 aMap[
"Pasty_Gorna"] =
"F.Paste";
1886 aMap[
"Opisowa_Dolna"] =
"B.SilkS";
1887 aMap[
"Opisowa_Gorna"] =
"F.SilkS";
1888 aMap[
"Maski_Dolna"] =
"B.Mask";
1889 aMap[
"Maski_Gorna"] =
"F.Mask";
1890 aMap[
"Rysunkowa"] =
"Dwgs.User";
1891 aMap[
"Komentarzy"] =
"Cmts.User";
1892 aMap[
"ECO1"] =
"Eco1.User";
1893 aMap[
"ECO2"] =
"Eco2.User";
1894 aMap[
"Krawedziowa"] =
"Edge.Cuts";
1897 aMap[
"Dessous.Adhes"] =
"B.Adhes";
1898 aMap[
"Dessus.Adhes"] =
"F.Adhes";
1899 aMap[
"Dessous.Pate"] =
"B.Paste";
1900 aMap[
"Dessus.Pate"] =
"F.Paste";
1901 aMap[
"Dessous.SilkS"] =
"B.SilkS";
1902 aMap[
"Dessus.SilkS"] =
"F.SilkS";
1903 aMap[
"Dessous.Masque"] =
"B.Mask";
1904 aMap[
"Dessus.Masque"] =
"F.Mask";
1905 aMap[
"Dessin.User"] =
"Dwgs.User";
1906 aMap[
"Contours.Ci"] =
"Edge.Cuts";
1912 wxCHECK_RET( CurTok() == T_layers,
1913 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layers." ) );
1918 int copperLayerCount = 0;
1920 bool anyHidden =
false;
1922 std::unordered_map< std::string, std::string > v3_layer_names;
1923 std::vector<LAYER> cu;
1927 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1934 cu.push_back( layer );
1947 for(
size_t i = 1; i < cu.size() - 1; i++ )
1956 tmpLayer = ( i + 1 ) * 2;
1958 cu[i].m_number = tmpLayer;
1961 cu[0].m_number =
F_Cu;
1962 cu[cu.size()-1].m_number =
B_Cu;
1964 for(
auto& cu_layer : cu )
1966 enabledLayers.
set( cu_layer.m_number );
1968 if( cu_layer.m_visible )
1969 visibleLayers.
set( cu_layer.m_number );
1981 copperLayerCount = cu.size();
1985 while( token != T_RIGHT )
1991 auto new_layer_it = v3_layer_names.find( layer.
m_name.ToStdString() );
1993 if( new_layer_it != v3_layer_names.end() )
1999 error.Printf(
_(
"Layer '%s' in file '%s' at line %d is not in fixed layer hash." ),
2012 layer.
m_name = it->first;
2027 if( token != T_LEFT )
2034 if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
2036 wxString err = wxString::Format(
_(
"%d is not a valid layer count" ), copperLayerCount );
2053 LSET_MAP::const_iterator it = aMap.find( curText );
2055 if( it == aMap.end() )
2065 LAYER_ID_MAP::const_iterator it = aMap.find( curText );
2067 if( it == aMap.end() )
2074 if( it->second ==
Rescue )
2084 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layer." ) );
2098 wxCHECK_MSG( CurTok() == T_layers,
LSET(),
2099 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as item layers." ) );
2103 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
2117 Expecting(
"single copper layer" );
2120 Expecting(
"max one soldermask layer" );
2124 Expecting(
"no mask layer when track is on internal layer" );
2127 Expecting(
"copper and mask on the same side" );
2130 Expecting(
"copper and mask on the same side" );
2138 wxCHECK_RET( CurTok() == T_setup,
2139 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as setup." ) );
2142 const std::shared_ptr<NETCLASS>& defaultNetClass = bds.
m_NetSettings->GetDefaultNetclass();
2149 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
2151 if( token != T_LEFT )
2152 Expecting( T_LEFT );
2162 case T_last_trace_width:
2167 case T_user_trace_width:
2183 case T_trace_clearance:
2184 defaultNetClass->SetClearance(
parseBoardUnits( T_trace_clearance ) );
2189 case T_zone_clearance:
2195 case T_zone_45_only:
2201 case T_clearance_min:
2225 case T_via_min_annulus:
2231 case T_via_min_size:
2237 case T_through_hole_min:
2244 case T_via_min_drill:
2250 case T_hole_to_hole_min:
2286 case T_uvias_allowed:
2292 case T_blind_buried_vias_allowed:
2298 case T_uvia_min_size:
2304 case T_uvia_min_drill:
2310 case T_user_diff_pair:
2325 case T_segment_width:
2337 case T_mod_edge_width:
2343 case T_pcb_text_width:
2349 case T_mod_text_width:
2355 case T_pcb_text_size:
2362 case T_mod_text_size:
2394 case T_pad_to_mask_clearance:
2399 case T_solder_mask_min_width:
2404 case T_pad_to_paste_clearance:
2409 case T_pad_to_paste_clearance_ratio:
2414 case T_allow_soldermask_bridges_in_footprints:
2421 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2423 if( token == T_front )
2425 else if( token == T_back )
2427 else if( token == T_none )
2430 Expecting(
"front, back, or none" );
2435 case T_aux_axis_origin:
2459 case T_visible_elements:
2466 for(
size_t i = 0; i <
sizeof( int ) * CHAR_BIT; i++ )
2479 case T_filled_areas_thickness:
2485 case T_pcbplotparams:
2491 parser.SyncLineReaderWith( *
this );
2493 plotParams.
Parse( &parser );
2494 SyncLineReaderWith( parser );
2509 Unexpected( CurText() );
2528 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2530 if( token != T_LEFT )
2531 Expecting( T_LEFT );
2537 case T_edge_clearance:
2543 case T_copper_line_width:
2548 case T_copper_text_dims:
2552 case T_courtyard_line_width:
2557 case T_edge_cuts_line_width:
2562 case T_silk_line_width:
2567 case T_silk_text_dims:
2571 case T_fab_layers_line_width:
2576 case T_fab_layers_text_dims:
2580 case T_other_layers_line_width:
2585 case T_other_layers_text_dims:
2589 case T_dimension_units:
2595 case T_dimension_precision:
2602 Unexpected( CurText() );
2612 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2614 if( token == T_LEFT )
2634 case T_keep_upright:
2639 Expecting(
"size, thickness, italic or keep_upright" );
2647 wxCHECK_RET( CurTok() == T_net,
2648 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net." ) );
2650 int netCode =
parseInt(
"net number" );
2652 NeedSYMBOLorNUMBER();
2653 wxString
name = FromUTF8();
2678 wxCHECK_RET( CurTok() == T_net_class,
2679 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net class." ) );
2683 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( wxEmptyString );
2686 NeedSYMBOLorNUMBER();
2687 nc->SetName( FromUTF8() );
2689 nc->SetDescription( FromUTF8() );
2691 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2693 if( token != T_LEFT )
2694 Expecting( T_LEFT );
2724 case T_diff_pair_width:
2728 case T_diff_pair_gap:
2734 NeedSYMBOLorNUMBER();
2736 wxString netName = FromUTF8();
2744 netName, nc->GetName() );
2750 Expecting(
"clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, "
2751 "diff_pair_width, diff_pair_gap or add_net" );
2759 if( netSettings->HasNetclass( nc->GetName() ) )
2764 error.Printf(
_(
"Duplicate NETCLASS name '%s' in file '%s' at line %d, offset %d." ),
2765 nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(),
2769 else if( nc->GetName() == netSettings->GetDefaultNetclass()->GetName() )
2771 netSettings->SetDefaultNetclass( nc );
2775 netSettings->SetNetclass( nc->GetName(), nc );
2782 wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
2783 CurTok() == T_fp_rect || CurTok() == T_fp_line || CurTok() == T_fp_poly ||
2784 CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
2785 CurTok() == T_gr_rect || CurTok() == T_gr_bbox || CurTok() == T_gr_line ||
2786 CurTok() == T_gr_poly || CurTok() == T_gr_vector,
nullptr,
2787 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_SHAPE." ) );
2792 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aParent );
2798 shape->SetShape( SHAPE_T::ARC );
2801 if( token == T_locked )
2803 shape->SetLocked(
true );
2807 if( token != T_LEFT )
2808 Expecting( T_LEFT );
2815 if( token != T_start )
2816 Expecting( T_start );
2820 shape->SetCenter( pt );
2826 if( token != T_end )
2831 shape->SetStart( pt );
2836 if( token != T_angle )
2837 Expecting( T_angle );
2844 VECTOR2I arc_start, arc_mid, arc_end;
2846 if( token != T_start )
2847 Expecting( T_start );
2855 if( token != T_mid )
2864 if( token != T_end )
2871 shape->SetArcGeometry( arc_start, arc_mid, arc_end );
2878 shape->SetShape( SHAPE_T::CIRCLE );
2881 if( token == T_locked )
2883 shape->SetLocked(
true );
2887 if( token != T_LEFT )
2888 Expecting( T_LEFT );
2892 if( token != T_center )
2893 Expecting( T_center );
2897 shape->SetStart( pt );
2903 if( token != T_end )
2908 shape->SetEnd( pt );
2914 shape->SetShape( SHAPE_T::BEZIER );
2917 if( token == T_locked )
2919 shape->SetLocked(
true );
2923 if( token != T_LEFT )
2924 Expecting( T_LEFT );
2928 if( token != T_pts )
2932 shape->SetBezierC1(
parseXY());
2933 shape->SetBezierC2(
parseXY());
2935 shape->RebuildBezierToSegmentsPointsList(
ARC_HIGH_DEF );
2942 shape->SetShape( SHAPE_T::RECTANGLE );
2945 if( token == T_locked )
2947 shape->SetLocked(
true );
2951 if( token != T_LEFT )
2952 Expecting( T_LEFT );
2956 if( token != T_start )
2957 Expecting( T_start );
2961 shape->SetStart( pt );
2966 if( token != T_end )
2971 shape->SetEnd( pt );
2992 if( token == T_locked )
2994 shape->SetLocked(
true );
2998 if( token != T_LEFT )
2999 Expecting( T_LEFT );
3003 if( token != T_start )
3004 Expecting( T_start );
3008 shape->SetStart( pt );
3013 if( token != T_end )
3018 shape->SetEnd( pt );
3025 shape->SetShape( SHAPE_T::POLY );
3026 shape->SetPolyPoints( {} );
3032 if( token == T_locked )
3034 shape->SetLocked(
true );
3038 if( token != T_LEFT )
3039 Expecting( T_LEFT );
3043 if( token != T_pts )
3046 while( (token = NextTok() ) != T_RIGHT )
3053 Expecting(
"gr_arc, gr_circle, gr_curve, gr_line, gr_poly, gr_rect or gr_bbox" );
3056 bool foundFill =
false;
3058 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3060 if( token != T_LEFT )
3061 Expecting( T_LEFT );
3081 case T_solder_mask_margin:
3082 shape->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
3094 strokeParser.SyncLineReaderWith( *
this );
3097 SyncLineReaderWith( strokeParser );
3111 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3113 if( token == T_LEFT )
3122 shape->SetFilled(
true );
3127 shape->SetFilled(
false );
3131 Expecting(
"yes, no, solid, none" );
3147 shape->SetLocked(
locked );
3154 wxLogError(
_(
"Invalid net ID in\nfile: '%s'\nline: %d\noffset: %d." ),
3155 CurSource(), CurLineNumber(), CurOffset() );
3161 Expecting(
"layer, width, fill, tstamp, uuid, locked, net, status, "
3162 "or solder_mask_margin" );
3171 && ( shape->GetShape() == SHAPE_T::RECTANGLE || shape->GetShape() == SHAPE_T::CIRCLE ) )
3173 shape->SetFilled(
true );
3175 else if( shape->GetShape() == SHAPE_T::POLY && shape->GetLayer() !=
Edge_Cuts )
3178 shape->SetFilled(
true );
3184 if( stroke.
GetWidth() <= 0 && !shape->IsFilled() )
3189 shape->SetStroke( stroke );
3193 shape->Rotate( { 0, 0 }, parentFP->GetOrientation() );
3194 shape->Move( parentFP->GetPosition() );
3197 return shape.release();
3203 wxCHECK_MSG( CurTok() == T_image,
nullptr,
3204 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a reference image." ) );
3207 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap = std::make_unique<PCB_REFERENCE_IMAGE>( aParent );
3209 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3211 if( token != T_LEFT )
3212 Expecting( T_LEFT );
3223 bitmap->SetPosition( pos );
3252 data.reserve( 1 << 19 );
3254 while( token != T_RIGHT )
3256 if( !IsSymbol( token ) )
3257 Expecting(
"base64 image data" );
3263 wxMemoryBuffer buffer = wxBase64Decode( data );
3276 bitmap->SetLocked(
locked );
3291 Expecting(
"at, layer, scale, data, locked or uuid" );
3295 return bitmap.release();
3301 wxCHECK_MSG( CurTok() == T_gr_text || CurTok() == T_fp_text,
nullptr,
3302 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXT." ) );
3305 std::unique_ptr<PCB_TEXT>
text;
3307 T token = NextTok();
3312 text = std::unique_ptr<PCB_TEXT>( aBaseText );
3327 text = std::make_unique<PCB_TEXT>( parentFP );
3331 THROW_IO_ERROR( wxString::Format(
_(
"Cannot handle footprint text type %s" ),
3339 text = std::make_unique<PCB_TEXT>( aParent );
3343 if( token == T_locked )
3345 text->SetLocked(
true );
3349 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
3350 Expecting(
"text value" );
3352 wxString value = FromUTF8();
3353 value.Replace( wxT(
"%V" ), wxT(
"${VALUE}" ) );
3354 value.Replace( wxT(
"%R" ), wxT(
"${REFERENCE}" ) );
3355 text->SetText( value );
3361 return text.release();
3368 bool hasAngle =
false;
3370 bool hasPos =
false;
3376 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
3378 if( token == T_LEFT )
3393 if( CurTok() == T_NUMBER )
3401 if( parentFP && CurTok() == T_unlocked )
3418 if( token == T_knockout )
3445 Expecting(
"layer, effects, locked, render_cache, uuid or tstamp" );
3461 Expecting(
"layer, effects, locked, render_cache or tstamp" );
3470 case T_render_cache:
3476 Expecting(
"layer, hide, effects, locked, render_cache or tstamp" );
3478 Expecting(
"layer, effects, locked, render_cache or tstamp" );
3508 wxCHECK_MSG( CurTok() == T_gr_text_box || CurTok() == T_fp_text_box,
nullptr,
3509 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXTBOX." ) );
3511 std::unique_ptr<PCB_TEXTBOX> textbox = std::make_unique<PCB_TEXTBOX>( aParent );
3515 return textbox.release();
3521 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
3522 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
3524 std::unique_ptr<PCB_TABLECELL> cell = std::make_unique<PCB_TABLECELL>( aParent );
3528 return cell.release();
3539 bool foundMargins =
false;
3541 T token = NextTok();
3544 if( token == T_locked )
3550 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
3551 Expecting(
"text value" );
3553 aTextBox->
SetText( FromUTF8() );
3555 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3557 if( token != T_LEFT )
3558 Expecting( T_LEFT );
3578 if( token != T_end )
3590 aTextBox->
SetShape( SHAPE_T::POLY );
3594 while( (token = NextTok() ) != T_RIGHT )
3610 strokeParser.SyncLineReaderWith( *
this );
3613 SyncLineReaderWith( strokeParser );
3628 foundMargins =
true;
3640 cell->SetColSpan(
parseInt(
"column span" ) );
3641 cell->SetRowSpan(
parseInt(
"row span" ) );
3645 Expecting(
"angle, width, layer, effects, render_cache, uuid or tstamp" );
3662 case T_render_cache:
3668 Expecting(
"locked, start, pts, angle, width, layer, effects, span, render_cache, uuid or tstamp" );
3670 Expecting(
"locked, start, pts, angle, width, layer, effects, render_cache, uuid or tstamp" );
3690 aTextBox->
Rotate( { 0, 0 }, parentFP->GetOrientation() );
3691 aTextBox->
Move( parentFP->GetPosition() );
3698 wxCHECK_MSG( CurTok() == T_table,
nullptr,
3699 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
3704 std::unique_ptr<PCB_TABLE> table = std::make_unique<PCB_TABLE>( aParent, -1 );
3706 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3708 if( token != T_LEFT )
3709 Expecting( T_LEFT );
3715 case T_column_count:
3716 table->SetColCount(
parseInt(
"column count" ) );
3735 case T_column_widths:
3739 while( ( token = NextTok() ) != T_RIGHT )
3749 while( ( token = NextTok() ) != T_RIGHT )
3756 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3758 if( token != T_LEFT )
3759 Expecting( T_LEFT );
3763 if( token != T_table_cell )
3764 Expecting(
"table_cell" );
3772 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3774 if( token != T_LEFT )
3775 Expecting( T_LEFT );
3782 table->SetStrokeExternal(
parseBool() );
3794 strokeParser.SyncLineReaderWith( *
this );
3797 SyncLineReaderWith( strokeParser );
3799 table->SetBorderStroke( borderStroke );
3804 Expecting(
"external, header or stroke" );
3812 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3814 if( token != T_LEFT )
3815 Expecting( T_LEFT );
3834 strokeParser.SyncLineReaderWith( *
this );
3837 SyncLineReaderWith( strokeParser );
3839 table->SetSeparatorsStroke( separatorsStroke );
3844 Expecting(
"rows, cols, or stroke" );
3852 Expecting(
"columns, layer, col_widths, row_heights, border, separators, header or "
3858 table->SetOrientation( table->GetOrientation() + parentFP->GetOrientation() );
3860 return table.release();
3866 wxCHECK_MSG( CurTok() == T_dimension,
nullptr,
3867 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as DIMENSION." ) );
3871 std::unique_ptr<PCB_DIMENSION_BASE> dim;
3876 if( token == T_locked )
3883 if( token != T_LEFT )
3888 bool isLegacyDimension =
false;
3889 bool isStyleKnown =
false;
3892 if( token == T_width )
3894 isLegacyDimension =
true;
3895 dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
3901 if( token != T_type )
3902 Expecting( T_type );
3906 case T_aligned: dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
break;
3907 case T_orthogonal: dim = std::make_unique<PCB_DIM_ORTHOGONAL>( aParent );
break;
3908 case T_leader: dim = std::make_unique<PCB_DIM_LEADER>( aParent );
break;
3909 case T_center: dim = std::make_unique<PCB_DIM_CENTER>( aParent );
break;
3910 case T_radial: dim = std::make_unique<PCB_DIM_RADIAL>( aParent );
break;
3911 default: wxFAIL_MSG( wxT(
"Cannot parse unknown dimension type " )
3912 + GetTokenString( CurTok() ) );
3918 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3920 if( token != T_LEFT )
3921 Expecting( T_LEFT );
3946 bool is_aligned = dim->GetKeepTextAligned();
3951 dim->SetTextPositionMode( DIM_TEXT_POSITION::MANUAL );
3952 dim->SetKeepTextAligned(
false );
3957 if( isLegacyDimension )
3959 EDA_UNITS units = EDA_UNITS::MILLIMETRES;
3962 dim->SetAutoUnits(
true );
3964 dim->SetUnits( units );
3969 dim->SetKeepTextAligned( is_aligned );
3970 dim->SetTextPositionMode( t_dim_pos );
3981 dim->SetStart( point );
3983 dim->SetEnd( point );
4003 case T_leader_length:
4019 int orientation =
parseInt(
"orthogonal dimension orientation" );
4025 orientation = std::clamp( orientation, 0, 1 );
4034 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4042 NeedSYMBOLorNUMBER();
4043 dim->SetPrefix( FromUTF8() );
4048 NeedSYMBOLorNUMBER();
4049 dim->SetSuffix( FromUTF8() );
4055 int mode =
parseInt(
"dimension units mode" );
4056 mode = std::max( 0, std::min( 4, mode ) );
4062 case T_units_format:
4064 int format =
parseInt(
"dimension units format" );
4065 format = std::clamp( format, 0, 3 );
4076 case T_override_value:
4077 NeedSYMBOLorNUMBER();
4078 dim->SetOverrideTextEnabled(
true );
4079 dim->SetOverrideText( FromUTF8() );
4083 case T_suppress_zeroes:
4084 dim->SetSuppressZeroes(
true );
4088 Expecting(
"prefix, suffix, units, units_format, precision, override_value, "
4089 "suppress_zeroes" );
4097 isStyleKnown =
true;
4100 dim->SetKeepTextAligned(
false );
4102 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4110 dim->SetLineThickness(
parseBoardUnits(
"extension line thickness value" ) );
4114 case T_arrow_length:
4119 case T_text_position_mode:
4121 int mode =
parseInt(
"text position mode" );
4122 mode = std::max( 0, std::min( 3, mode ) );
4128 case T_extension_height:
4131 wxCHECK_MSG( aligned,
nullptr, wxT(
"Invalid extension_height token" ) );
4137 case T_extension_offset:
4138 dim->SetExtensionOffset(
parseBoardUnits(
"extension offset value" ) );
4142 case T_keep_text_aligned:
4143 dim->SetKeepTextAligned(
true );
4149 wxT(
"Invalid text_frame token" ) );
4153 int textFrame =
parseInt(
"text frame mode" );
4154 textFrame = std::clamp( textFrame, 0, 3 );
4161 Expecting(
"thickness, arrow_length, text_position_mode, extension_height, "
4162 "extension_offset" );
4175 if( token != T_pts )
4181 dim->SetStart( point );
4195 if( token != T_pts )
4201 dim->SetEnd( point );
4215 if( token == T_pts )
4237 if( token != T_pts )
4251 if( token != T_pts )
4265 if( token != T_pts )
4279 if( token != T_pts )
4293 dim->SetLocked( isLocked );
4298 Expecting(
"layer, tstamp, uuid, gr_text, feature1, feature2, crossbar, arrow1a, "
4299 "arrow1b, arrow2a, or arrow2b" );
4304 dim->SetLocked(
true );
4308 return dim.release();
4330 wxCHECK_MSG( CurTok() == T_module || CurTok() == T_footprint,
nullptr,
4331 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FOOTPRINT." ) );
4339 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
4341 footprint->SetInitialComments( aInitialComments );
4350 if( !IsSymbol( token ) && token != T_NUMBER )
4351 Expecting(
"symbol|number" );
4357 THROW_IO_ERROR( wxString::Format(
_(
"Invalid footprint ID in\nfile: %s\nline: %d\n"
4359 CurSource(), CurLineNumber(), CurOffset() ) );
4372 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4374 if( token == T_LEFT )
4384 int this_version =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
4388 footprint->SetFileFormatVersionAtLoad( this_version );
4399 case T_generator_version:
4446 footprint->SetPosition( pt );
4449 if( token == T_NUMBER )
4454 else if( token != T_RIGHT )
4456 Expecting( T_RIGHT );
4462 NeedSYMBOLorNUMBER();
4463 footprint->SetLibDescription( FromUTF8() );
4468 NeedSYMBOLorNUMBER();
4469 footprint->SetKeywords( FromUTF8() );
4478 wxString pName = FromUTF8();
4480 wxString pValue = FromUTF8();
4488 if( pName ==
"ki_keywords" || pName ==
"ki_locked" )
4496 if( pName ==
"ki_description" )
4504 if( pName ==
"Sheetfile" || pName ==
"Sheet file" )
4506 footprint->SetSheetfile( pValue );
4511 if( pName ==
"Sheetname" || pName ==
"Sheet name" )
4513 footprint->SetSheetname( pValue );
4521 if( pName ==
"ki_fp_filters" )
4523 footprint->SetFilters( pValue );
4541 if( footprint->HasFieldByName( pName ) )
4543 field = footprint->GetFieldByName( pName );
4548 field = footprint->AddField(
PCB_FIELD( footprint.get(), footprint->GetFieldCount(),
4570 NeedSYMBOLorNUMBER();
4571 footprint->SetPath(
KIID_PATH( FromUTF8() ) );
4577 footprint->SetSheetname( FromUTF8() );
4583 footprint->SetSheetfile( FromUTF8() );
4587 case T_autoplace_cost90:
4588 case T_autoplace_cost180:
4589 parseInt(
"legacy auto-place cost" );
4593 case T_private_layers:
4597 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4602 privateLayers.
set( it->second );
4604 Expecting(
"layer name" );
4613 footprint->SetPrivateLayers( privateLayers );
4617 case T_net_tie_pad_groups:
4618 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4619 footprint->AddNetTiePadGroup( CurStr() );
4623 case T_solder_mask_margin:
4624 footprint->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
4628 if( m_requiredVersion <= 20240201 && footprint->GetLocalSolderMaskMargin() == 0 )
4629 footprint->SetLocalSolderMaskMargin( {} );
4633 case T_solder_paste_margin:
4634 footprint->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
4638 if( m_requiredVersion <= 20240201 && footprint->GetLocalSolderPasteMargin() == 0 )
4639 footprint->SetLocalSolderPasteMargin( {} );
4643 case T_solder_paste_ratio:
4644 case T_solder_paste_margin_ratio:
4645 footprint->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
4649 if( m_requiredVersion <= 20240201 && footprint->GetLocalSolderPasteMarginRatio() == 0 )
4650 footprint->SetLocalSolderPasteMarginRatio( {} );
4655 footprint->SetLocalClearance(
parseBoardUnits(
"local clearance value" ) );
4659 if( m_requiredVersion <= 20240201 && footprint->GetLocalClearance() == 0 )
4660 footprint->SetLocalClearance( {} );
4664 case T_zone_connect:
4669 case T_thermal_width:
4677 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4685 case T_through_hole:
4697 case T_exclude_from_pos_files:
4701 case T_exclude_from_bom:
4705 case T_allow_missing_courtyard:
4713 case T_allow_soldermask_bridges:
4718 Expecting(
"through_hole, smd, virtual, board_only, exclude_from_pos_files, "
4719 "exclude_from_bom or allow_solder_mask_bridges" );
4733 switch( field->GetId() )
4737 const_cast<KIID&
>( footprint->Reference().m_Uuid ) =
text->m_Uuid;
4743 const_cast<KIID&
>( footprint->Value().m_Uuid ) =
text->m_Uuid;
4749 footprint->Add(
text, ADD_MODE::APPEND,
true );
4757 footprint->Add( textbox, ADD_MODE::APPEND,
true );
4764 footprint->Add( table, ADD_MODE::APPEND,
true );
4776 footprint->Add( shape, ADD_MODE::APPEND,
true );
4783 footprint->Add(
image, ADD_MODE::APPEND,
true );
4790 footprint->Add( dimension, ADD_MODE::APPEND,
true );
4797 footprint->Add(
pad, ADD_MODE::APPEND,
true );
4804 footprint->Add3DModel( model );
4812 footprint->Add( zone, ADD_MODE::APPEND,
true );
4820 case T_embedded_fonts:
4822 footprint->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
4827 case T_embedded_files:
4830 embeddedFilesParser.SyncLineReaderWith( *
this );
4834 embeddedFilesParser.
ParseEmbedded( footprint->GetEmbeddedFiles() );
4838 wxLogError( e.
What() );
4841 SyncLineReaderWith( embeddedFilesParser );
4845 case T_component_classes:
4847 std::unordered_set<wxString> componentClassNames;
4849 while( ( token = NextTok() ) != T_RIGHT )
4851 if( token != T_LEFT )
4852 Expecting( T_LEFT );
4854 if( ( token = NextTok() ) != T_class )
4855 Expecting( T_class );
4857 NeedSYMBOLorNUMBER();
4858 componentClassNames.insert(
From_UTF8( CurText() ) );
4866 componentClassNames );
4867 footprint->SetComponentClass( componentClass );
4874 Expecting(
"at, descr, locked, placed, tedit, tstamp, uuid, "
4875 "autoplace_cost90, autoplace_cost180, attr, clearance, "
4876 "embedded_files, fp_arc, fp_circle, fp_curve, fp_line, fp_poly, "
4877 "fp_rect, fp_text, pad, group, generator, model, path, solder_mask_margin, "
4878 "solder_paste_margin, solder_paste_margin_ratio, tags, thermal_gap, "
4879 "version, zone, zone_connect, or component_classes" );
4893 if( footprint->GetKeywords().StartsWith( wxT(
"net tie" ) ) )
4897 for(
PAD*
pad : footprint->Pads() )
4899 if( !padGroup.IsEmpty() )
4900 padGroup += wxS(
", " );
4902 padGroup +=
pad->GetNumber();
4905 if( !padGroup.IsEmpty() )
4906 footprint->AddNetTiePadGroup( padGroup );
4910 footprint->SetAttributes( attributes );
4912 footprint->SetFPID( fpid );
4914 return footprint.release();
4920 wxCHECK_MSG( CurTok() == T_pad,
nullptr,
4921 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PAD." ) );
4925 bool foundNet =
false;
4927 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
4929 NeedSYMBOLorNUMBER();
4930 pad->SetNumber( FromUTF8() );
4932 T token = NextTok();
4937 pad->SetAttribute( PAD_ATTRIB::PTH );
4946 pad->SetAttribute( PAD_ATTRIB::SMD );
4954 pad->SetAttribute( PAD_ATTRIB::CONN );
4961 case T_np_thru_hole:
4962 pad->SetAttribute( PAD_ATTRIB::NPTH );
4966 Expecting(
"thru_hole, smd, connect, or np_thru_hole" );
5000 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
5003 std::optional<EDA_ANGLE> thermalBrAngleOverride;
5005 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5007 if( token == T_locked )
5013 if( token != T_LEFT )
5014 Expecting( T_LEFT );
5030 pad->SetFPRelativePosition( pt );
5033 if( token == T_NUMBER )
5038 else if( token != T_RIGHT )
5040 Expecting(
") or angle value" );
5057 bool haveWidth =
false;
5060 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5062 if( token == T_LEFT )
5067 case T_oval:
pad->SetDrillShape( PAD_DRILL_SHAPE::OBLONG );
break;
5076 drillSize.
y = drillSize.
x;
5095 Expecting(
"oval, size, or offset" );
5103 if(
pad->GetAttribute() != PAD_ATTRIB::SMD &&
pad->GetAttribute() != PAD_ATTRIB::CONN )
5104 pad->SetDrillSize( drillSize );
5114 pad->SetLayerSet( layerMask );
5123 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d offset: %d" ),
5124 CurSource(), CurLineNumber(), CurOffset() );
5127 NeedSYMBOLorNUMBER();
5132 wxString netName( FromUTF8() );
5142 wxLogError(
_(
"Net name doesn't match ID in\nfile: %s\nline: %d offset: %d" ),
5143 CurSource(), CurLineNumber(), CurOffset() );
5151 NeedSYMBOLorNUMBER();
5152 pad->SetPinFunction( FromUTF8() );
5157 NeedSYMBOLorNUMBER();
5158 pad->SetPinType( FromUTF8() );
5167 case T_solder_mask_margin:
5168 pad->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
5172 if( m_requiredVersion <= 20240201 && pad->GetLocalSolderMaskMargin() == 0 )
5173 pad->SetLocalSolderMaskMargin( {} );
5177 case T_solder_paste_margin:
5178 pad->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
5182 if( m_requiredVersion <= 20240201 && pad->GetLocalSolderPasteMargin() == 0 )
5183 pad->SetLocalSolderPasteMargin( {} );
5187 case T_solder_paste_margin_ratio:
5188 pad->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
5192 if( m_requiredVersion <= 20240201 && pad->GetLocalSolderPasteMarginRatio() == 0 )
5193 pad->SetLocalSolderPasteMarginRatio( {} );
5202 if( m_requiredVersion <= 20240201 && pad->GetLocalClearance() == 0 )
5203 pad->SetLocalClearance( {} );
5211 case T_zone_connect:
5216 case T_thermal_width:
5217 case T_thermal_bridge_width:
5222 case T_thermal_bridge_angle:
5233 case T_roundrect_rratio:
5239 case T_chamfer_ratio:
5251 bool end_list =
false;
5271 case T_bottom_right:
5281 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
5282 "chamfer_bottom_right" );
5293 while( token != T_RIGHT )
5299 case T_pad_prop_bga:
pad->SetProperty( PAD_PROP::BGA );
break;
5300 case T_pad_prop_fiducial_glob:
pad->SetProperty( PAD_PROP::FIDUCIAL_GLBL );
break;
5301 case T_pad_prop_fiducial_loc:
pad->SetProperty( PAD_PROP::FIDUCIAL_LOCAL );
break;
5302 case T_pad_prop_testpoint:
pad->SetProperty( PAD_PROP::TESTPOINT );
break;
5303 case T_pad_prop_castellated:
pad->SetProperty( PAD_PROP::CASTELLATED );
break;
5304 case T_pad_prop_heatsink:
pad->SetProperty( PAD_PROP::HEATSINK );
break;
5305 case T_pad_prop_mechanical:
pad->SetProperty( PAD_PROP::MECHANICAL );
break;
5306 case T_none:
pad->SetProperty( PAD_PROP::NONE );
break;
5307 case T_RIGHT:
break;
5311 Expecting(
"pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc"
5312 " pad_prop_heatsink or pad_prop_castellated" );
5329 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5331 if( token == T_LEFT )
5362 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
5369 case T_remove_unused_layers:
5372 pad->SetRemoveUnconnected( remove );
5376 case T_keep_end_layers:
5379 pad->SetKeepTopBottom( keep );
5383 case T_zone_layer_connections:
5390 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5395 Expecting(
"copper layer name" );
5417 Expecting(
"at, locked, drill, layers, net, die_length, roundrect_rratio, "
5418 "solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, uuid, "
5419 "clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
5420 "pinfunction, pintype, zone_connect, thermal_width, thermal_gap, padstack or "
5428 pad->SetNetCode( 0,
true );
5431 if( thermalBrAngleOverride )
5433 pad->SetThermalSpokeAngle( *thermalBrAngleOverride );
5456 if( !
pad->CanHaveNumber() )
5460 pad->SetNumber( wxEmptyString );
5464 if(
pad->GetSizeX() <= 0 ||
pad->GetSizeY() <= 0 )
5469 wxLogWarning(
_(
"Invalid zero-sized pad pinned to %s in\nfile: %s\nline: %d\noffset: %d" ),
5470 wxT(
"1µm" ), CurSource(), CurLineNumber(), CurOffset() );
5473 return pad.release();
5480 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
5482 if( token != T_LEFT )
5483 Expecting( T_LEFT );
5538 while( (token = NextTok() ) != T_RIGHT )
5553 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
5555 if( token != T_LEFT )
5556 Expecting( T_LEFT );
5567 case T_front_inner_back:
5576 Expecting(
"front_inner_back or custom" );
5587 if( curText ==
"Inner" )
5591 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
5592 "line: %d\noffset: %d." ),
5593 CurSource(), CurLineNumber(), CurOffset() ) );
5606 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
5607 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
5611 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5613 if( token != T_LEFT )
5614 Expecting( T_LEFT );
5626 aPad->
SetShape( curLayer, PAD_SHAPE::CIRCLE );
5630 aPad->
SetShape( curLayer, PAD_SHAPE::RECTANGLE );
5634 aPad->
SetShape( curLayer, PAD_SHAPE::OVAL );
5638 aPad->
SetShape( curLayer, PAD_SHAPE::TRAPEZOID );
5644 aPad->
SetShape( curLayer, PAD_SHAPE::ROUNDRECT );
5648 aPad->
SetShape( curLayer, PAD_SHAPE::CUSTOM );
5652 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
5663 aPad->
SetSize( curLayer, sz );
5688 case T_roundrect_rratio:
5694 case T_chamfer_ratio:
5700 aPad->
SetShape( curLayer, PAD_SHAPE::CHAMFERED_RECT );
5709 bool end_list =
false;
5729 case T_bottom_right:
5739 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
5740 "chamfer_bottom_right" );
5745 aPad->
SetShape( curLayer, PAD_SHAPE::CHAMFERED_RECT );
5750 case T_thermal_bridge_width:
5761 case T_thermal_bridge_angle:
5767 case T_zone_connect:
5768 padstack.
ZoneConnection( curLayer ) = magic_enum::enum_cast<ZONE_CONNECTION>(
5769 parseInt(
"zone connection value" ) );
5785 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5787 if( token != T_LEFT )
5788 Expecting( T_LEFT );
5826 while( ( token = NextTok() ) != T_RIGHT )
5839 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5841 if( token == T_LEFT )
5872 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
5889 Expecting(
"mode or layer" );
5900 while( ( token = NextTok() ) != T_RIGHT )
5905 KIID uuid( CurStr() );
5913 wxCHECK_RET( CurTok() == T_group,
5914 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
5920 groupInfo.
parent = aParent;
5922 while( ( token = NextTok() ) != T_LEFT )
5924 if( token == T_STRING )
5925 groupInfo.
name = FromUTF8();
5926 else if( token == T_locked )
5929 Expecting(
"group name or locked" );
5932 for( ; token != T_RIGHT; token = NextTok() )
5934 if( token != T_LEFT )
5935 Expecting( T_LEFT );
5961 Expecting(
"uuid, locked, or members" );
5969 wxCHECK_RET( CurTok() == T_generated, wxT(
"Cannot parse " ) + GetTokenString( CurTok() )
5970 + wxT(
" as PCB_GENERATOR." ) );
5978 genInfo.
parent = aParent;
5985 if( token != T_uuid && token != T_id )
5986 Expecting( T_uuid );
5992 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5994 if( token != T_LEFT )
5995 Expecting( T_LEFT );
6009 genInfo.
name = FromUTF8();
6015 genInfo.
locked = token == T_yes;
6028 wxString pName = FromUTF8();
6035 genInfo.
properties.emplace( pName, wxAny(
true ) );
6041 genInfo.
properties.emplace( pName, wxAny(
false ) );
6048 genInfo.
properties.emplace( pName, wxAny( pValue ) );
6054 wxString pValue = FromUTF8();
6073 genInfo.
properties.emplace( pName, wxAny( pt ) );
6083 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6088 genInfo.
properties.emplace( pName, wxAny( chain ) );
6091 default: Expecting(
"xy or pts" );
6096 default: Expecting(
"a number, symbol, string or (" );
6108 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
6109 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ARC." ) );
6114 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board );
6116 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6119 if( token == T_locked )
6121 arc->SetLocked(
true );
6125 if( token != T_LEFT )
6126 Expecting( T_LEFT );
6135 arc->SetStart( pt );
6167 case T_solder_mask_margin:
6168 arc->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6175 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d\noffset: %d." ),
6176 CurSource(), CurLineNumber(), CurOffset() );
6199 Expecting(
"start, mid, end, width, layer, solder_mask_margin, net, tstamp, uuid, "
6204 return arc.release();
6210 wxCHECK_MSG( CurTok() == T_segment,
nullptr,
6211 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TRACK." ) );
6216 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
6218 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6221 if( token == T_locked )
6223 track->SetLocked(
true );
6227 if( token != T_LEFT )
6228 Expecting( T_LEFT );
6237 track->SetStart( pt );
6244 track->SetEnd( pt );
6262 case T_solder_mask_margin:
6263 track->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6270 wxLogError(
_(
"Invalid net ID in\nfile: '%s'\nline: %d\noffset: %d." ),
6271 CurSource(), CurLineNumber(), CurOffset() );
6294 Expecting(
"start, end, width, layer, solder_mask_margin, net, tstamp, uuid, "
6299 return track.release();
6305 wxCHECK_MSG( CurTok() == T_via,
nullptr,
6306 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_VIA." ) );
6311 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
6316 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6319 if( token == T_locked )
6321 via->SetLocked(
true );
6325 if( token == T_LEFT )
6331 via->SetViaType( VIATYPE::BLIND_BURIED );
6335 via->SetViaType( VIATYPE::MICROVIA );
6341 via->SetStart( pt );
6363 via->SetLayerPair( layer1, layer2 );
6366 Expecting(
"layer name" );
6375 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d\noffset: %d" ),
6376 CurSource(), CurLineNumber(), CurOffset() );
6382 case T_remove_unused_layers:
6385 via->SetRemoveUnconnected( remove );
6389 case T_keep_end_layers:
6392 via->SetKeepStartEnd( keep );
6396 case T_zone_layer_connections:
6406 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6411 Expecting(
"copper layer name" );
6452 Expecting(
"blind, micro, at, size, drill, layers, net, free, tstamp, uuid, status or "
6457 return via.release();
6467 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
6469 if( token == T_front )
6471 else if( token == T_back )
6473 else if( token != T_none )
6474 Expecting(
"front, back, or none" );
6486 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
6488 if( token != T_LEFT )
6489 Expecting( T_LEFT );
6500 case T_front_inner_back:
6509 Expecting(
"front_inner_back or custom" );
6520 if( curText ==
"Inner" )
6524 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
6525 "line: %d\noffset: %d." ),
6526 CurSource(), CurLineNumber(), CurOffset() ) );
6539 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
6540 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
6544 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6546 if( token != T_LEFT )
6547 Expecting( T_LEFT );
6557 padstack.
SetSize( { diameter, diameter }, curLayer );
6564 Expecting(
"size" );
6572 Expecting(
"mode or layer" );
6581 wxCHECK_MSG( CurTok() == T_zone,
nullptr,
6582 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ZONE." ) );
6589 wxString netnameFromfile;
6592 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
6593 std::map<PCB_LAYER_ID, std::vector<SEG>> legacySegs;
6595 bool addedFilledPolygons =
false;
6596 bool isStrokedFill =
true;
6598 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aParent );
6600 zone->SetAssignedPriority( 0 );
6603 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::ALWAYS );
6605 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6608 if( token == T_locked )
6610 zone->SetLocked(
true );
6614 if( token == T_LEFT )
6628 if( !zone->SetNetCode( tmp,
true ) )
6630 wxLogError(
_(
"Invalid net ID in\nfile: %s;\nline: %d\noffset: %d." ),
6631 CurSource(), CurLineNumber(), CurOffset() );
6638 NeedSYMBOLorNUMBER();
6639 netnameFromfile = FromUTF8();
6662 if( token != T_none && token != T_edge && token != T_full )
6663 Expecting(
"none, edge, or full" );
6668 case T_none: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH;
break;
6669 case T_edge: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE;
break;
6670 case T_full: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL;
break;
6678 zone->SetAssignedPriority(
parseInt(
"zone priority" ) );
6682 case T_connect_pads:
6683 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6685 if( token == T_LEFT )
6691 zone->SetPadConnection( ZONE_CONNECTION::FULL );
6695 zone->SetPadConnection( ZONE_CONNECTION::NONE );
6698 case T_thru_hole_only:
6699 zone->SetPadConnection( ZONE_CONNECTION::THT_THERMAL );
6708 Expecting(
"yes, no, or clearance" );
6714 case T_min_thickness:
6719 case T_filled_areas_thickness:
6726 isStrokedFill =
false;
6732 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6734 if( token == T_LEFT )
6740 zone->SetIsFilled(
true );
6746 if( token != T_segment && token != T_hatch && token != T_polygon )
6747 Expecting(
"segment, hatch or polygon" );
6752 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
6758 zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
6765 case T_hatch_thickness:
6775 case T_hatch_orientation:
6778 zone->SetHatchOrientation( orientation );
6783 case T_hatch_smoothing_level:
6784 zone->SetHatchSmoothingLevel(
parseDouble( T_hatch_smoothing_level ) );
6788 case T_hatch_smoothing_value:
6789 zone->SetHatchSmoothingValue(
parseDouble( T_hatch_smoothing_value ) );
6793 case T_hatch_border_algorithm:
6796 if( token != T_hatch_thickness && token != T_min_thickness )
6797 Expecting(
"hatch_thickness or min_thickness" );
6799 zone->SetHatchBorderAlgorithm( token == T_hatch_thickness ? 1 : 0 );
6803 case T_hatch_min_hole_area:
6804 zone->SetHatchHoleMinArea(
parseDouble( T_hatch_min_hole_area ) );
6808 case T_arc_segments:
6818 case T_thermal_bridge_width:
6819 zone->SetThermalReliefSpokeWidth(
parseBoardUnits( T_thermal_bridge_width ) );
6831 if( !zone->GetIsRuleArea() )
6837 if( !zone->GetIsRuleArea() )
6843 Expecting(
"none, chamfer, or fillet" );
6852 if( !zone->GetIsRuleArea() )
6853 zone->SetCornerRadius( tmp );
6858 case T_island_removal_mode:
6859 tmp =
parseInt(
"island_removal_mode" );
6861 if( tmp >= 0 && tmp <= 2 )
6867 case T_island_area_min:
6876 Expecting(
"mode, arc_segments, thermal_gap, thermal_bridge_width, "
6877 "hatch_thickness, hatch_gap, hatch_orientation, "
6878 "hatch_smoothing_level, hatch_smoothing_value, "
6879 "hatch_border_algorithm, hatch_min_hole_area, smoothing, radius, "
6880 "island_removal_mode, or island_area_min" );
6887 zone->SetIsRuleArea(
true );
6889 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6891 if( token == T_LEFT )
6898 zone->SetRuleAreaPlacementSourceType(
6899 RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME );
6901 zone->SetRuleAreaPlacementSource( FromUTF8() );
6904 case T_component_class:
6906 zone->SetRuleAreaPlacementSourceType(
6907 RULE_AREA_PLACEMENT_SOURCE_TYPE::COMPONENT_CLASS );
6909 zone->SetRuleAreaPlacementSource( FromUTF8() );
6916 if( token == T_yes )
6917 zone->SetRuleAreaPlacementEnabled(
true );
6918 else if( token == T_no )
6919 zone->SetRuleAreaPlacementEnabled(
false );
6921 Expecting(
"yes or no" );
6927 Expecting(
"enabled, sheetname or component_class" );
6939 zone->SetIsRuleArea(
true );
6942 zone->SetDoNotAllowPads(
false );
6943 zone->SetDoNotAllowFootprints(
false );
6945 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6947 if( token == T_LEFT )
6955 if( token != T_allowed && token != T_not_allowed )
6956 Expecting(
"allowed or not_allowed" );
6958 zone->SetDoNotAllowTracks( token == T_not_allowed );
6964 if( token != T_allowed && token != T_not_allowed )
6965 Expecting(
"allowed or not_allowed" );
6967 zone->SetDoNotAllowVias( token == T_not_allowed );
6973 if( token != T_allowed && token != T_not_allowed )
6974 Expecting(
"allowed or not_allowed" );
6976 zone->SetDoNotAllowCopperPour( token == T_not_allowed );
6982 if( token != T_allowed && token != T_not_allowed )
6983 Expecting(
"allowed or not_allowed" );
6985 zone->SetDoNotAllowPads( token == T_not_allowed );
6991 if( token != T_allowed && token != T_not_allowed )
6992 Expecting(
"allowed or not_allowed" );
6994 zone->SetDoNotAllowFootprints( token == T_not_allowed );
6998 Expecting(
"tracks, vias or copperpour" );
7013 if( token != T_pts )
7016 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7025 zone->AddPolygon( outline );
7029 case T_filled_polygon:
7035 if( token == T_layer )
7041 if( token != T_LEFT )
7042 Expecting( T_LEFT );
7049 filledLayer = zone->GetFirstLayer();
7052 bool island =
false;
7054 if( token == T_island )
7062 if( token != T_pts )
7065 if( !pts.count( filledLayer ) )
7074 zone->SetIsIsland( filledLayer, idx );
7076 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7081 addedFilledPolygons |= !poly.
IsEmpty();
7086 case T_fill_segments:
7090 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7092 if( token != T_LEFT )
7093 Expecting( T_LEFT );
7097 if( token != T_pts )
7101 filledLayer = zone->GetFirstLayer();
7108 legacySegs[filledLayer].push_back( fillSegment );
7118 zone->SetZoneName( FromUTF8() );
7123 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7125 if( token == T_LEFT )
7131 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7133 if( token == T_LEFT )
7141 if( token == T_padvia )
7142 zone->SetTeardropAreaType( TEARDROP_TYPE::TD_VIAPAD );
7143 else if( token == T_track_end )
7144 zone->SetTeardropAreaType( TEARDROP_TYPE::TD_TRACKEND );
7146 Expecting(
"padvia or track_end" );
7152 Expecting(
"type" );
7159 Expecting(
"teardrop" );
7170 Expecting(
"net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
7171 "fill, polygon, filled_polygon, fill_segments, attr, locked, uuid, or name" );
7175 if( zone->GetNumCorners() > 2 )
7177 if( !zone->IsOnCopperLayer() )
7184 zone->SetBorderDisplayStyle( hatchStyle, hatchPitch,
true );
7187 if( addedFilledPolygons )
7189 if( isStrokedFill && !zone->GetIsRuleArea() )
7194 _(
"Legacy zone fill strategy is not supported anymore.\nZone fills will "
7195 "be converted on best-effort basis." ) );
7200 if( zone->GetMinThickness() > 0 )
7202 for(
auto& [layer, polyset] : pts )
7204 polyset.InflateWithLinkedHoles( zone->GetMinThickness() / 2,
7205 CORNER_STRATEGY::ROUND_ALL_CORNERS,
7212 for(
auto& [layer, polyset] : pts )
7213 zone->SetFilledPolysList( layer, polyset );
7215 zone->CalculateFilledArea();
7217 else if( legacySegs.size() > 0 )
7225 wxLogWarning(
_(
"The legacy segment zone fill mode is no longer supported.\n"
7226 "Zone fills will be converted on a best-effort basis." ) );
7232 for(
const auto& [layer, segments] : legacySegs )
7236 if( zone->HasFilledPolysForLayer( layer ) )
7239 for(
const auto& seg : segments )
7250 zone->SetFilledPolysList( layer, layerFill );
7251 zone->CalculateFilledArea();
7259 bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsRuleArea();
7266 && ( !zone->GetNet() || zone->GetNet()->GetNetname() != netnameFromfile ) )
7295 zone->SetNeedRefill(
false );
7297 return zone.release();
7303 wxCHECK_MSG( CurTok() == T_target,
nullptr,
7304 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TARGET." ) );
7309 std::unique_ptr<PCB_TARGET> target = std::make_unique<PCB_TARGET>(
nullptr );
7311 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7313 if( token == T_LEFT )
7319 target->SetShape( 1 );
7323 target->SetShape( 0 );
7329 target->SetPosition( pt );
7356 Expecting(
"x, plus, at, size, width, layer, uuid, or tstamp" );
7360 return target.release();
7367 std::string idStr( CurStr() );
7370 if( *idStr.begin() ==
'"' && *idStr.rbegin() ==
'"' )
7371 idStr = idStr.substr( 1, idStr.length() - 1 );
7380 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)
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]
void SetBoardThickness(int aThickness)
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...
virtual void SetLocked(bool aLocked)
virtual void SetIsKnockout(bool aKnockout)
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
FOOTPRINT * GetParentFootprint() const
BOARD_ITEM_CONTAINER * GetParent() const
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction) const
Invoke a function on all children.
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_CastellatedPads
True if castellated pads exist.
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.
void SetPlotOptions(const PCB_PLOT_PARAMS &aOptions)
bool m_LegacyDesignSettingsLoaded
True if the legacy board design settings were loaded from a file.
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
EMBEDDED_FILES * GetEmbeddedFiles() override
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
GAL_SET m_LegacyVisibleItems
void SetEnabledLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
void SetProperties(const std::map< wxString, wxString > &aProps)
bool SetLayerDescr(PCB_LAYER_ID aIndex, const LAYER &aLayer)
Return the type of the copper layer given by aLayer.
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
const ZONES & Zones() const
void FixupEmbeddedData()
After loading a file from disk, the footprints do not yet contain the full data for their embedded fi...
PCB_LAYER_ID GetLayerID(const wxString &aLayerName) const
Return the ID of a layer.
LSET m_LegacyVisibleLayers
Visibility settings stored in board prior to 6.0, only used for loading legacy files.
int GetCopperLayerCount() const
const FOOTPRINTS & Footprints() const
const TRACKS & Tracks() const
void SetPageSettings(const PAGE_INFO &aPageSettings)
bool m_LegacyNetclassesLoaded
True if netclasses were loaded from the file.
void SetCopperLayerCount(int aCount)
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
void SetLegacyTeardrops(bool aFlag)
void FinalizeBulkAdd(std::vector< BOARD_ITEM * > &aNewItems)
Must be used if Add() is used using a BULK_x ADD_MODE to generate a change event for listeners.
wxString GroupsSanityCheck(bool repair=false)
Consistency check of internal m_groups structure.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
void SetGenerator(const wxString &aGenerator)
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
unsigned GetNetCount() const
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
bool m_LegacyCopperEdgeClearanceLoaded
const DRAWINGS & Drawings() const
void SetFileFormatVersionAtLoad(int aVersion)
const COMPONENT_CLASS * GetNoneComponentClass() const
Returns the unassigned component class.
COMPONENT_CLASS * GetEffectiveComponentClass(std::unordered_set< wxString > &classNames)
Gets an effective component class for the given constituent class names.
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)
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 italic 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.
void SetAreFontsEmbedded(bool aEmbedFonts)
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()
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
A color representation with 4 components: red, green, blue, alpha.
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.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
LSET is a set of PCB_LAYER_IDs.
static LSET InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static int NameToLayer(wxString &aName)
Return the layer number from a layer name.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Handle the data for a net.
const wxString & GetNetname() const
void SetNetCode(int aNetCode)
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...
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 SetChamferRectRatio(PCB_LAYER_ID aLayer, double aChamferScale)
Has meaning only for chamfered rectangular pads.
const PADSTACK & Padstack() const
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 SetCustomShapeInZoneOpt(PADSTACK::CUSTOM_SHAPE_ZONE_MODE aOption)
Set the option for the custom pad shape to use as clearance area in copper zones.
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.
static const wxChar Custom[]
"User" defined page type
void SetWidthMM(double aWidthInMM)
void SetHeightMM(double aHeightInMM)
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
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
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
int getNetCode(int aNetCode)
void createOldLayerMapping(std::unordered_map< std::string, std::string > &aMap)
Create a mapping from the (short-lived) bug where layer names were translated.
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 parseTextBoxContent(PCB_TEXTBOX *aTextBox)
FOOTPRINT * parseFOOTPRINT(wxArrayString *aInitialComments=nullptr)
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::map< EDA_TEXT *, std::tuple< wxString, bool, bool > > m_fontTextMap
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 parseTenting(PADSTACK &aPadstack)
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
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
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()
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)
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) 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
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
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.
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)
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset union For aFastMode meaning, see function booleanOp.
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...
int m_CurveSegCount
True if the teardrop should be curved.
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.
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.
Handle a list of polygons defining a copper zone.
void SetLayerSet(const LSET &aLayerSet) override
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
static int GetDefaultHatchPitch()
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
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
void ignore_unused(const T &)
#define THROW_IO_ERROR(msg)
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
#define MIN_VISIBILITY_MASK
bool IsCopperLayer(int aLayerId)
Tests 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)
Writes any unit info found in the string to aUnits.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
#define MAX_PAGE_SIZE_PCBNEW_MM
#define MIN_PAGE_SIZE_MM
Min and max page sizes for clamping, in mm.
DIM_TEXT_POSITION
Where to place the text on a dimension.
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.
int StrPrintf(std::string *result, const char *format,...)
This is like sprintf() but the output is appended to a std::string instead of to a character array.
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,...
constexpr int mmToIU(double mm) const
Container to hold information pertinent to a layer of a BOARD.
static LAYER_T ParseType(const char *aType)
Convert a string to a LAYER_T.
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.
std::optional< bool > has_solder_mask
True if this outer layer has mask (is not tented)
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...
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
@ DESCRIPTION_FIELD
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ 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)
@ NOT_USED
the 3d code uses this value
@ 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.