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" ) );
3734 case T_column_widths:
3738 while( ( token = NextTok() ) != T_RIGHT )
3748 while( ( token = NextTok() ) != T_RIGHT )
3755 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3757 if( token != T_LEFT )
3758 Expecting( T_LEFT );
3762 if( token != T_table_cell )
3763 Expecting(
"table_cell" );
3771 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3773 if( token != T_LEFT )
3774 Expecting( T_LEFT );
3781 table->SetStrokeExternal(
parseBool() );
3793 strokeParser.SyncLineReaderWith( *
this );
3796 SyncLineReaderWith( strokeParser );
3798 table->SetBorderStroke( borderStroke );
3803 Expecting(
"external, header or stroke" );
3811 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3813 if( token != T_LEFT )
3814 Expecting( T_LEFT );
3833 strokeParser.SyncLineReaderWith( *
this );
3836 SyncLineReaderWith( strokeParser );
3838 table->SetSeparatorsStroke( separatorsStroke );
3843 Expecting(
"rows, cols, or stroke" );
3851 Expecting(
"columns, layer, col_widths, row_heights, border, separators, header or "
3856 return table.release();
3862 wxCHECK_MSG( CurTok() == T_dimension,
nullptr,
3863 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as DIMENSION." ) );
3867 std::unique_ptr<PCB_DIMENSION_BASE> dim;
3872 if( token == T_locked )
3879 if( token != T_LEFT )
3884 bool isLegacyDimension =
false;
3885 bool isStyleKnown =
false;
3888 if( token == T_width )
3890 isLegacyDimension =
true;
3891 dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
3897 if( token != T_type )
3898 Expecting( T_type );
3902 case T_aligned: dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
break;
3903 case T_orthogonal: dim = std::make_unique<PCB_DIM_ORTHOGONAL>( aParent );
break;
3904 case T_leader: dim = std::make_unique<PCB_DIM_LEADER>( aParent );
break;
3905 case T_center: dim = std::make_unique<PCB_DIM_CENTER>( aParent );
break;
3906 case T_radial: dim = std::make_unique<PCB_DIM_RADIAL>( aParent );
break;
3907 default: wxFAIL_MSG( wxT(
"Cannot parse unknown dimension type " )
3908 + GetTokenString( CurTok() ) );
3915 dim->SetArrowDirection( DIM_ARROW_DIRECTION::OUTWARD );
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:
4088 std::cerr <<
"Unknown format token: " << GetTokenString( token ) << std::endl;
4089 Expecting(
"prefix, suffix, units, units_format, precision, override_value, "
4090 "suppress_zeroes" );
4098 isStyleKnown =
true;
4101 dim->SetKeepTextAligned(
false );
4103 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4111 dim->SetLineThickness(
parseBoardUnits(
"extension line thickness value" ) );
4115 case T_arrow_direction:
4119 if( token == T_inward )
4120 dim->ChangeArrowDirection( DIM_ARROW_DIRECTION::INWARD );
4121 else if( token == T_outward )
4122 dim->ChangeArrowDirection( DIM_ARROW_DIRECTION::OUTWARD );
4124 Expecting(
"inward or outward" );
4129 case T_arrow_length:
4135 case T_text_position_mode:
4137 int mode =
parseInt(
"text position mode" );
4138 mode = std::max( 0, std::min( 3, mode ) );
4144 case T_extension_height:
4147 wxCHECK_MSG( aligned,
nullptr, wxT(
"Invalid extension_height token" ) );
4153 case T_extension_offset:
4154 dim->SetExtensionOffset(
parseBoardUnits(
"extension offset value" ) );
4158 case T_keep_text_aligned:
4165 wxT(
"Invalid text_frame token" ) );
4169 int textFrame =
parseInt(
"text frame mode" );
4170 textFrame = std::clamp( textFrame, 0, 3 );
4177 Expecting(
"thickness, arrow_length, arrow_direction, text_position_mode, "
4178 "extension_height, extension_offset" );
4191 if( token != T_pts )
4197 dim->SetStart( point );
4211 if( token != T_pts )
4217 dim->SetEnd( point );
4231 if( token == T_pts )
4253 if( token != T_pts )
4267 if( token != T_pts )
4281 if( token != T_pts )
4295 if( token != T_pts )
4309 dim->SetLocked( isLocked );
4314 Expecting(
"layer, tstamp, uuid, gr_text, feature1, feature2, crossbar, arrow1a, "
4315 "arrow1b, arrow2a, or arrow2b" );
4320 dim->SetLocked(
true );
4324 return dim.release();
4346 wxCHECK_MSG( CurTok() == T_module || CurTok() == T_footprint,
nullptr,
4347 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FOOTPRINT." ) );
4355 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
4357 footprint->SetInitialComments( aInitialComments );
4366 if( !IsSymbol( token ) && token != T_NUMBER )
4367 Expecting(
"symbol|number" );
4373 THROW_IO_ERROR( wxString::Format(
_(
"Invalid footprint ID in\nfile: %s\nline: %d\n"
4375 CurSource(), CurLineNumber(), CurOffset() ) );
4388 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4390 if( token == T_LEFT )
4400 int this_version =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
4404 footprint->SetFileFormatVersionAtLoad( this_version );
4415 case T_generator_version:
4462 footprint->SetPosition( pt );
4465 if( token == T_NUMBER )
4470 else if( token != T_RIGHT )
4472 Expecting( T_RIGHT );
4478 NeedSYMBOLorNUMBER();
4479 footprint->SetLibDescription( FromUTF8() );
4484 NeedSYMBOLorNUMBER();
4485 footprint->SetKeywords( FromUTF8() );
4494 wxString pName = FromUTF8();
4496 wxString pValue = FromUTF8();
4504 if( pName ==
"ki_keywords" || pName ==
"ki_locked" )
4512 if( pName ==
"ki_description" )
4520 if( pName ==
"Sheetfile" || pName ==
"Sheet file" )
4522 footprint->SetSheetfile( pValue );
4527 if( pName ==
"Sheetname" || pName ==
"Sheet name" )
4529 footprint->SetSheetname( pValue );
4537 if( pName ==
"ki_fp_filters" )
4539 footprint->SetFilters( pValue );
4556 std::unique_ptr<PCB_FIELD> unusedField;
4558 if( pName ==
"Footprint" )
4563 unusedField = std::make_unique<PCB_FIELD>( footprint.get(), 0 );
4564 field = unusedField.get();
4566 else if( footprint->HasFieldByName( pName ) )
4568 field = footprint->GetFieldByName( pName );
4573 field = footprint->AddField(
PCB_FIELD( footprint.get(), footprint->GetFieldCount(),
4595 NeedSYMBOLorNUMBER();
4596 footprint->SetPath(
KIID_PATH( FromUTF8() ) );
4602 footprint->SetSheetname( FromUTF8() );
4608 footprint->SetSheetfile( FromUTF8() );
4612 case T_autoplace_cost90:
4613 case T_autoplace_cost180:
4614 parseInt(
"legacy auto-place cost" );
4618 case T_private_layers:
4622 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4627 privateLayers.
set( it->second );
4629 Expecting(
"layer name" );
4638 footprint->SetPrivateLayers( privateLayers );
4642 case T_net_tie_pad_groups:
4643 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4644 footprint->AddNetTiePadGroup( CurStr() );
4648 case T_solder_mask_margin:
4649 footprint->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
4653 if( m_requiredVersion <= 20240201 && footprint->GetLocalSolderMaskMargin() == 0 )
4654 footprint->SetLocalSolderMaskMargin( {} );
4658 case T_solder_paste_margin:
4659 footprint->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
4663 if( m_requiredVersion <= 20240201 && footprint->GetLocalSolderPasteMargin() == 0 )
4664 footprint->SetLocalSolderPasteMargin( {} );
4668 case T_solder_paste_ratio:
4669 case T_solder_paste_margin_ratio:
4670 footprint->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
4674 if( m_requiredVersion <= 20240201 && footprint->GetLocalSolderPasteMarginRatio() == 0 )
4675 footprint->SetLocalSolderPasteMarginRatio( {} );
4680 footprint->SetLocalClearance(
parseBoardUnits(
"local clearance value" ) );
4684 if( m_requiredVersion <= 20240201 && footprint->GetLocalClearance() == 0 )
4685 footprint->SetLocalClearance( {} );
4689 case T_zone_connect:
4694 case T_thermal_width:
4702 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4710 case T_through_hole:
4722 case T_exclude_from_pos_files:
4726 case T_exclude_from_bom:
4730 case T_allow_missing_courtyard:
4738 case T_allow_soldermask_bridges:
4743 Expecting(
"through_hole, smd, virtual, board_only, exclude_from_pos_files, "
4744 "exclude_from_bom or allow_solder_mask_bridges" );
4758 switch( field->GetId() )
4762 const_cast<KIID&
>( footprint->Reference().m_Uuid ) =
text->m_Uuid;
4770 const_cast<KIID&
>( footprint->Value().m_Uuid ) =
text->m_Uuid;
4777 footprint->Add(
text, ADD_MODE::APPEND,
true );
4785 footprint->Add( textbox, ADD_MODE::APPEND,
true );
4792 footprint->Add( table, ADD_MODE::APPEND,
true );
4804 footprint->Add( shape, ADD_MODE::APPEND,
true );
4811 footprint->Add(
image, ADD_MODE::APPEND,
true );
4818 footprint->Add( dimension, ADD_MODE::APPEND,
true );
4825 footprint->Add(
pad, ADD_MODE::APPEND,
true );
4832 footprint->Add3DModel( model );
4840 footprint->Add( zone, ADD_MODE::APPEND,
true );
4848 case T_embedded_fonts:
4850 footprint->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
4855 case T_embedded_files:
4858 embeddedFilesParser.SyncLineReaderWith( *
this );
4862 embeddedFilesParser.
ParseEmbedded( footprint->GetEmbeddedFiles() );
4866 wxLogError( e.
What() );
4869 SyncLineReaderWith( embeddedFilesParser );
4873 case T_component_classes:
4875 std::unordered_set<wxString> componentClassNames;
4877 while( ( token = NextTok() ) != T_RIGHT )
4879 if( token != T_LEFT )
4880 Expecting( T_LEFT );
4882 if( ( token = NextTok() ) != T_class )
4883 Expecting( T_class );
4885 NeedSYMBOLorNUMBER();
4886 componentClassNames.insert(
From_UTF8( CurText() ) );
4894 componentClassNames );
4895 footprint->SetComponentClass( componentClass );
4902 Expecting(
"at, descr, locked, placed, tedit, tstamp, uuid, "
4903 "autoplace_cost90, autoplace_cost180, attr, clearance, "
4904 "embedded_files, fp_arc, fp_circle, fp_curve, fp_line, fp_poly, "
4905 "fp_rect, fp_text, pad, group, generator, model, path, solder_mask_margin, "
4906 "solder_paste_margin, solder_paste_margin_ratio, tags, thermal_gap, "
4907 "version, zone, zone_connect, or component_classes" );
4921 if( footprint->GetKeywords().StartsWith( wxT(
"net tie" ) ) )
4925 for(
PAD*
pad : footprint->Pads() )
4927 if( !padGroup.IsEmpty() )
4928 padGroup += wxS(
", " );
4930 padGroup +=
pad->GetNumber();
4933 if( !padGroup.IsEmpty() )
4934 footprint->AddNetTiePadGroup( padGroup );
4938 footprint->SetAttributes( attributes );
4940 footprint->SetFPID( fpid );
4942 return footprint.release();
4948 wxCHECK_MSG( CurTok() == T_pad,
nullptr,
4949 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PAD." ) );
4953 bool foundNet =
false;
4955 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
4957 NeedSYMBOLorNUMBER();
4958 pad->SetNumber( FromUTF8() );
4960 T token = NextTok();
4965 pad->SetAttribute( PAD_ATTRIB::PTH );
4974 pad->SetAttribute( PAD_ATTRIB::SMD );
4982 pad->SetAttribute( PAD_ATTRIB::CONN );
4989 case T_np_thru_hole:
4990 pad->SetAttribute( PAD_ATTRIB::NPTH );
4994 Expecting(
"thru_hole, smd, connect, or np_thru_hole" );
5028 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
5031 std::optional<EDA_ANGLE> thermalBrAngleOverride;
5033 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5035 if( token == T_locked )
5041 if( token != T_LEFT )
5042 Expecting( T_LEFT );
5058 pad->SetFPRelativePosition( pt );
5061 if( token == T_NUMBER )
5066 else if( token != T_RIGHT )
5068 Expecting(
") or angle value" );
5085 bool haveWidth =
false;
5088 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5090 if( token == T_LEFT )
5095 case T_oval:
pad->SetDrillShape( PAD_DRILL_SHAPE::OBLONG );
break;
5104 drillSize.
y = drillSize.
x;
5123 Expecting(
"oval, size, or offset" );
5131 if(
pad->GetAttribute() != PAD_ATTRIB::SMD &&
pad->GetAttribute() != PAD_ATTRIB::CONN )
5132 pad->SetDrillSize( drillSize );
5142 pad->SetLayerSet( layerMask );
5151 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d offset: %d" ),
5152 CurSource(), CurLineNumber(), CurOffset() );
5155 NeedSYMBOLorNUMBER();
5160 wxString netName( FromUTF8() );
5170 wxLogError(
_(
"Net name doesn't match ID in\nfile: %s\nline: %d offset: %d" ),
5171 CurSource(), CurLineNumber(), CurOffset() );
5179 NeedSYMBOLorNUMBER();
5180 pad->SetPinFunction( FromUTF8() );
5185 NeedSYMBOLorNUMBER();
5186 pad->SetPinType( FromUTF8() );
5195 case T_solder_mask_margin:
5196 pad->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
5200 if( m_requiredVersion <= 20240201 && pad->GetLocalSolderMaskMargin() == 0 )
5201 pad->SetLocalSolderMaskMargin( {} );
5205 case T_solder_paste_margin:
5206 pad->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
5210 if( m_requiredVersion <= 20240201 && pad->GetLocalSolderPasteMargin() == 0 )
5211 pad->SetLocalSolderPasteMargin( {} );
5215 case T_solder_paste_margin_ratio:
5216 pad->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
5220 if( m_requiredVersion <= 20240201 && pad->GetLocalSolderPasteMarginRatio() == 0 )
5221 pad->SetLocalSolderPasteMarginRatio( {} );
5230 if( m_requiredVersion <= 20240201 && pad->GetLocalClearance() == 0 )
5231 pad->SetLocalClearance( {} );
5239 case T_zone_connect:
5244 case T_thermal_width:
5245 case T_thermal_bridge_width:
5250 case T_thermal_bridge_angle:
5261 case T_roundrect_rratio:
5267 case T_chamfer_ratio:
5279 bool end_list =
false;
5299 case T_bottom_right:
5309 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
5310 "chamfer_bottom_right" );
5321 while( token != T_RIGHT )
5327 case T_pad_prop_bga:
pad->SetProperty( PAD_PROP::BGA );
break;
5328 case T_pad_prop_fiducial_glob:
pad->SetProperty( PAD_PROP::FIDUCIAL_GLBL );
break;
5329 case T_pad_prop_fiducial_loc:
pad->SetProperty( PAD_PROP::FIDUCIAL_LOCAL );
break;
5330 case T_pad_prop_testpoint:
pad->SetProperty( PAD_PROP::TESTPOINT );
break;
5331 case T_pad_prop_castellated:
pad->SetProperty( PAD_PROP::CASTELLATED );
break;
5332 case T_pad_prop_heatsink:
pad->SetProperty( PAD_PROP::HEATSINK );
break;
5333 case T_pad_prop_mechanical:
pad->SetProperty( PAD_PROP::MECHANICAL );
break;
5334 case T_none:
pad->SetProperty( PAD_PROP::NONE );
break;
5335 case T_RIGHT:
break;
5339 Expecting(
"pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc"
5340 " pad_prop_heatsink or pad_prop_castellated" );
5357 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5359 if( token == T_LEFT )
5390 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
5397 case T_remove_unused_layers:
5400 pad->SetRemoveUnconnected( remove );
5404 case T_keep_end_layers:
5407 pad->SetKeepTopBottom( keep );
5411 case T_zone_layer_connections:
5418 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5423 Expecting(
"copper layer name" );
5445 Expecting(
"at, locked, drill, layers, net, die_length, roundrect_rratio, "
5446 "solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, uuid, "
5447 "clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
5448 "pinfunction, pintype, zone_connect, thermal_width, thermal_gap, padstack or "
5456 pad->SetNetCode( 0,
true );
5459 if( thermalBrAngleOverride )
5461 pad->SetThermalSpokeAngle( *thermalBrAngleOverride );
5484 if( !
pad->CanHaveNumber() )
5488 pad->SetNumber( wxEmptyString );
5492 if(
pad->GetSizeX() <= 0 ||
pad->GetSizeY() <= 0 )
5497 wxLogWarning(
_(
"Invalid zero-sized pad pinned to %s in\nfile: %s\nline: %d\noffset: %d" ),
5498 wxT(
"1µm" ), CurSource(), CurLineNumber(), CurOffset() );
5501 return pad.release();
5508 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
5510 if( token != T_LEFT )
5511 Expecting( T_LEFT );
5566 while( (token = NextTok() ) != T_RIGHT )
5581 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
5583 if( token != T_LEFT )
5584 Expecting( T_LEFT );
5595 case T_front_inner_back:
5604 Expecting(
"front_inner_back or custom" );
5615 if( curText ==
"Inner" )
5619 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
5620 "line: %d\noffset: %d." ),
5621 CurSource(), CurLineNumber(), CurOffset() ) );
5634 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
5635 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
5639 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5641 if( token != T_LEFT )
5642 Expecting( T_LEFT );
5654 aPad->
SetShape( curLayer, PAD_SHAPE::CIRCLE );
5658 aPad->
SetShape( curLayer, PAD_SHAPE::RECTANGLE );
5662 aPad->
SetShape( curLayer, PAD_SHAPE::OVAL );
5666 aPad->
SetShape( curLayer, PAD_SHAPE::TRAPEZOID );
5672 aPad->
SetShape( curLayer, PAD_SHAPE::ROUNDRECT );
5676 aPad->
SetShape( curLayer, PAD_SHAPE::CUSTOM );
5680 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
5691 aPad->
SetSize( curLayer, sz );
5716 case T_roundrect_rratio:
5722 case T_chamfer_ratio:
5728 aPad->
SetShape( curLayer, PAD_SHAPE::CHAMFERED_RECT );
5737 bool end_list =
false;
5757 case T_bottom_right:
5767 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
5768 "chamfer_bottom_right" );
5773 aPad->
SetShape( curLayer, PAD_SHAPE::CHAMFERED_RECT );
5778 case T_thermal_bridge_width:
5789 case T_thermal_bridge_angle:
5795 case T_zone_connect:
5796 padstack.
ZoneConnection( curLayer ) = magic_enum::enum_cast<ZONE_CONNECTION>(
5797 parseInt(
"zone connection value" ) );
5813 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5815 if( token != T_LEFT )
5816 Expecting( T_LEFT );
5854 while( ( token = NextTok() ) != T_RIGHT )
5867 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5869 if( token == T_LEFT )
5900 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
5917 Expecting(
"mode or layer" );
5928 while( ( token = NextTok() ) != T_RIGHT )
5933 KIID uuid( CurStr() );
5941 wxCHECK_RET( CurTok() == T_group,
5942 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
5948 groupInfo.
parent = aParent;
5950 while( ( token = NextTok() ) != T_LEFT )
5952 if( token == T_STRING )
5953 groupInfo.
name = FromUTF8();
5954 else if( token == T_locked )
5957 Expecting(
"group name or locked" );
5960 for( ; token != T_RIGHT; token = NextTok() )
5962 if( token != T_LEFT )
5963 Expecting( T_LEFT );
5989 Expecting(
"uuid, locked, or members" );
5997 wxCHECK_RET( CurTok() == T_generated, wxT(
"Cannot parse " ) + GetTokenString( CurTok() )
5998 + wxT(
" as PCB_GENERATOR." ) );
6006 genInfo.
parent = aParent;
6013 if( token != T_uuid && token != T_id )
6014 Expecting( T_uuid );
6020 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6022 if( token != T_LEFT )
6023 Expecting( T_LEFT );
6037 genInfo.
name = FromUTF8();
6043 genInfo.
locked = token == T_yes;
6056 wxString pName = FromUTF8();
6063 genInfo.
properties.emplace( pName, wxAny(
true ) );
6069 genInfo.
properties.emplace( pName, wxAny(
false ) );
6076 genInfo.
properties.emplace( pName, wxAny( pValue ) );
6082 wxString pValue = FromUTF8();
6101 genInfo.
properties.emplace( pName, wxAny( pt ) );
6111 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6116 genInfo.
properties.emplace( pName, wxAny( chain ) );
6119 default: Expecting(
"xy or pts" );
6124 default: Expecting(
"a number, symbol, string or (" );
6136 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
6137 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ARC." ) );
6142 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board );
6144 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6147 if( token == T_locked )
6149 arc->SetLocked(
true );
6153 if( token != T_LEFT )
6154 Expecting( T_LEFT );
6163 arc->SetStart( pt );
6195 case T_solder_mask_margin:
6196 arc->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6203 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d\noffset: %d." ),
6204 CurSource(), CurLineNumber(), CurOffset() );
6227 Expecting(
"start, mid, end, width, layer, solder_mask_margin, net, tstamp, uuid, "
6232 return arc.release();
6238 wxCHECK_MSG( CurTok() == T_segment,
nullptr,
6239 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TRACK." ) );
6244 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
6246 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6249 if( token == T_locked )
6251 track->SetLocked(
true );
6255 if( token != T_LEFT )
6256 Expecting( T_LEFT );
6265 track->SetStart( pt );
6272 track->SetEnd( pt );
6290 case T_solder_mask_margin:
6291 track->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6298 wxLogError(
_(
"Invalid net ID in\nfile: '%s'\nline: %d\noffset: %d." ),
6299 CurSource(), CurLineNumber(), CurOffset() );
6322 Expecting(
"start, end, width, layer, solder_mask_margin, net, tstamp, uuid, "
6327 return track.release();
6333 wxCHECK_MSG( CurTok() == T_via,
nullptr,
6334 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_VIA." ) );
6339 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
6344 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6347 if( token == T_locked )
6349 via->SetLocked(
true );
6353 if( token == T_LEFT )
6359 via->SetViaType( VIATYPE::BLIND_BURIED );
6363 via->SetViaType( VIATYPE::MICROVIA );
6369 via->SetStart( pt );
6391 via->SetLayerPair( layer1, layer2 );
6394 Expecting(
"layer name" );
6403 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d\noffset: %d" ),
6404 CurSource(), CurLineNumber(), CurOffset() );
6410 case T_remove_unused_layers:
6413 via->SetRemoveUnconnected( remove );
6417 case T_keep_end_layers:
6420 via->SetKeepStartEnd( keep );
6424 case T_zone_layer_connections:
6434 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6439 Expecting(
"copper layer name" );
6480 Expecting(
"blind, micro, at, size, drill, layers, net, free, tstamp, uuid, status or "
6485 return via.release();
6495 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
6497 if( token == T_front )
6499 else if( token == T_back )
6501 else if( token != T_none )
6502 Expecting(
"front, back, or none" );
6514 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
6516 if( token != T_LEFT )
6517 Expecting( T_LEFT );
6528 case T_front_inner_back:
6537 Expecting(
"front_inner_back or custom" );
6548 if( curText ==
"Inner" )
6552 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
6553 "line: %d\noffset: %d." ),
6554 CurSource(), CurLineNumber(), CurOffset() ) );
6567 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
6568 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
6572 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6574 if( token != T_LEFT )
6575 Expecting( T_LEFT );
6585 padstack.
SetSize( { diameter, diameter }, curLayer );
6592 Expecting(
"size" );
6600 Expecting(
"mode or layer" );
6609 wxCHECK_MSG( CurTok() == T_zone,
nullptr,
6610 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ZONE." ) );
6617 wxString netnameFromfile;
6620 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
6621 std::map<PCB_LAYER_ID, std::vector<SEG>> legacySegs;
6623 bool addedFilledPolygons =
false;
6624 bool isStrokedFill =
true;
6626 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aParent );
6628 zone->SetAssignedPriority( 0 );
6631 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::ALWAYS );
6633 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6636 if( token == T_locked )
6638 zone->SetLocked(
true );
6642 if( token == T_LEFT )
6656 if( !zone->SetNetCode( tmp,
true ) )
6658 wxLogError(
_(
"Invalid net ID in\nfile: %s;\nline: %d\noffset: %d." ),
6659 CurSource(), CurLineNumber(), CurOffset() );
6666 NeedSYMBOLorNUMBER();
6667 netnameFromfile = FromUTF8();
6690 if( token != T_none && token != T_edge && token != T_full )
6691 Expecting(
"none, edge, or full" );
6696 case T_none: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH;
break;
6697 case T_edge: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE;
break;
6698 case T_full: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL;
break;
6706 zone->SetAssignedPriority(
parseInt(
"zone priority" ) );
6710 case T_connect_pads:
6711 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6713 if( token == T_LEFT )
6719 zone->SetPadConnection( ZONE_CONNECTION::FULL );
6723 zone->SetPadConnection( ZONE_CONNECTION::NONE );
6726 case T_thru_hole_only:
6727 zone->SetPadConnection( ZONE_CONNECTION::THT_THERMAL );
6736 Expecting(
"yes, no, or clearance" );
6742 case T_min_thickness:
6747 case T_filled_areas_thickness:
6754 isStrokedFill =
false;
6760 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6762 if( token == T_LEFT )
6768 zone->SetIsFilled(
true );
6774 if( token != T_segment && token != T_hatch && token != T_polygon )
6775 Expecting(
"segment, hatch or polygon" );
6780 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
6786 zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
6793 case T_hatch_thickness:
6803 case T_hatch_orientation:
6806 zone->SetHatchOrientation( orientation );
6811 case T_hatch_smoothing_level:
6812 zone->SetHatchSmoothingLevel(
parseDouble( T_hatch_smoothing_level ) );
6816 case T_hatch_smoothing_value:
6817 zone->SetHatchSmoothingValue(
parseDouble( T_hatch_smoothing_value ) );
6821 case T_hatch_border_algorithm:
6824 if( token != T_hatch_thickness && token != T_min_thickness )
6825 Expecting(
"hatch_thickness or min_thickness" );
6827 zone->SetHatchBorderAlgorithm( token == T_hatch_thickness ? 1 : 0 );
6831 case T_hatch_min_hole_area:
6832 zone->SetHatchHoleMinArea(
parseDouble( T_hatch_min_hole_area ) );
6836 case T_arc_segments:
6846 case T_thermal_bridge_width:
6847 zone->SetThermalReliefSpokeWidth(
parseBoardUnits( T_thermal_bridge_width ) );
6859 if( !zone->GetIsRuleArea() )
6865 if( !zone->GetIsRuleArea() )
6871 Expecting(
"none, chamfer, or fillet" );
6880 if( !zone->GetIsRuleArea() )
6881 zone->SetCornerRadius( tmp );
6886 case T_island_removal_mode:
6887 tmp =
parseInt(
"island_removal_mode" );
6889 if( tmp >= 0 && tmp <= 2 )
6895 case T_island_area_min:
6904 Expecting(
"mode, arc_segments, thermal_gap, thermal_bridge_width, "
6905 "hatch_thickness, hatch_gap, hatch_orientation, "
6906 "hatch_smoothing_level, hatch_smoothing_value, "
6907 "hatch_border_algorithm, hatch_min_hole_area, smoothing, radius, "
6908 "island_removal_mode, or island_area_min" );
6915 zone->SetIsRuleArea(
true );
6917 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6919 if( token == T_LEFT )
6926 zone->SetRuleAreaPlacementSourceType(
6927 RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME );
6929 zone->SetRuleAreaPlacementSource( FromUTF8() );
6932 case T_component_class:
6934 zone->SetRuleAreaPlacementSourceType(
6935 RULE_AREA_PLACEMENT_SOURCE_TYPE::COMPONENT_CLASS );
6937 zone->SetRuleAreaPlacementSource( FromUTF8() );
6944 if( token == T_yes )
6945 zone->SetRuleAreaPlacementEnabled(
true );
6946 else if( token == T_no )
6947 zone->SetRuleAreaPlacementEnabled(
false );
6949 Expecting(
"yes or no" );
6955 Expecting(
"enabled, sheetname or component_class" );
6967 zone->SetIsRuleArea(
true );
6970 zone->SetDoNotAllowPads(
false );
6971 zone->SetDoNotAllowFootprints(
false );
6973 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6975 if( token == T_LEFT )
6983 if( token != T_allowed && token != T_not_allowed )
6984 Expecting(
"allowed or not_allowed" );
6986 zone->SetDoNotAllowTracks( token == T_not_allowed );
6992 if( token != T_allowed && token != T_not_allowed )
6993 Expecting(
"allowed or not_allowed" );
6995 zone->SetDoNotAllowVias( token == T_not_allowed );
7001 if( token != T_allowed && token != T_not_allowed )
7002 Expecting(
"allowed or not_allowed" );
7004 zone->SetDoNotAllowCopperPour( token == T_not_allowed );
7010 if( token != T_allowed && token != T_not_allowed )
7011 Expecting(
"allowed or not_allowed" );
7013 zone->SetDoNotAllowPads( token == T_not_allowed );
7019 if( token != T_allowed && token != T_not_allowed )
7020 Expecting(
"allowed or not_allowed" );
7022 zone->SetDoNotAllowFootprints( token == T_not_allowed );
7026 Expecting(
"tracks, vias or copperpour" );
7041 if( token != T_pts )
7044 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7053 zone->AddPolygon( outline );
7057 case T_filled_polygon:
7063 if( token == T_layer )
7069 if( token != T_LEFT )
7070 Expecting( T_LEFT );
7077 filledLayer = zone->GetFirstLayer();
7080 bool island =
false;
7082 if( token == T_island )
7090 if( token != T_pts )
7093 if( !pts.count( filledLayer ) )
7102 zone->SetIsIsland( filledLayer, idx );
7104 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7109 addedFilledPolygons |= !poly.
IsEmpty();
7114 case T_fill_segments:
7118 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7120 if( token != T_LEFT )
7121 Expecting( T_LEFT );
7125 if( token != T_pts )
7129 filledLayer = zone->GetFirstLayer();
7136 legacySegs[filledLayer].push_back( fillSegment );
7146 zone->SetZoneName( FromUTF8() );
7151 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7153 if( token == T_LEFT )
7159 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7161 if( token == T_LEFT )
7169 if( token == T_padvia )
7170 zone->SetTeardropAreaType( TEARDROP_TYPE::TD_VIAPAD );
7171 else if( token == T_track_end )
7172 zone->SetTeardropAreaType( TEARDROP_TYPE::TD_TRACKEND );
7174 Expecting(
"padvia or track_end" );
7180 Expecting(
"type" );
7187 Expecting(
"teardrop" );
7198 Expecting(
"net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
7199 "fill, polygon, filled_polygon, fill_segments, attr, locked, uuid, or name" );
7203 if( zone->GetNumCorners() > 2 )
7205 if( !zone->IsOnCopperLayer() )
7212 zone->SetBorderDisplayStyle( hatchStyle, hatchPitch,
true );
7215 if( addedFilledPolygons )
7217 if( isStrokedFill && !zone->GetIsRuleArea() )
7222 _(
"Legacy zone fill strategy is not supported anymore.\nZone fills will "
7223 "be converted on best-effort basis." ) );
7228 if( zone->GetMinThickness() > 0 )
7230 for(
auto& [layer, polyset] : pts )
7232 polyset.InflateWithLinkedHoles( zone->GetMinThickness() / 2,
7233 CORNER_STRATEGY::ROUND_ALL_CORNERS,
7240 for(
auto& [layer, polyset] : pts )
7241 zone->SetFilledPolysList( layer, polyset );
7243 zone->CalculateFilledArea();
7245 else if( legacySegs.size() > 0 )
7253 wxLogWarning(
_(
"The legacy segment zone fill mode is no longer supported.\n"
7254 "Zone fills will be converted on a best-effort basis." ) );
7260 for(
const auto& [layer, segments] : legacySegs )
7264 if( zone->HasFilledPolysForLayer( layer ) )
7267 for(
const auto& seg : segments )
7278 zone->SetFilledPolysList( layer, layerFill );
7279 zone->CalculateFilledArea();
7287 bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsRuleArea();
7294 && ( !zone->GetNet() || zone->GetNet()->GetNetname() != netnameFromfile ) )
7323 zone->SetNeedRefill(
false );
7325 return zone.release();
7331 wxCHECK_MSG( CurTok() == T_target,
nullptr,
7332 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TARGET." ) );
7337 std::unique_ptr<PCB_TARGET> target = std::make_unique<PCB_TARGET>(
nullptr );
7339 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7341 if( token == T_LEFT )
7347 target->SetShape( 1 );
7351 target->SetShape( 0 );
7357 target->SetPosition( pt );
7384 Expecting(
"x, plus, at, size, width, layer, uuid, or tstamp" );
7388 return target.release();
7410 std::string idStr( CurStr() );
7413 if( *idStr.begin() ==
'"' && *idStr.rbegin() ==
'"' )
7414 idStr = idStr.substr( 1, idStr.length() - 1 );
7423 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)
void removeReplaceEntryInFontTextMap(EDA_TEXT *aEntry, EDA_TEXT *aReplacer)
Remove an entry from m_fontTextMap.
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.