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() ) );
3919 dim->SetArrowDirection( DIM_ARROW_DIRECTION::OUTWARD );
3922 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3924 if( token != T_LEFT )
3925 Expecting( T_LEFT );
3950 bool is_aligned = dim->GetKeepTextAligned();
3955 dim->SetTextPositionMode( DIM_TEXT_POSITION::MANUAL );
3956 dim->SetKeepTextAligned(
false );
3961 if( isLegacyDimension )
3963 EDA_UNITS units = EDA_UNITS::MILLIMETRES;
3966 dim->SetAutoUnits(
true );
3968 dim->SetUnits( units );
3973 dim->SetKeepTextAligned( is_aligned );
3974 dim->SetTextPositionMode( t_dim_pos );
3985 dim->SetStart( point );
3987 dim->SetEnd( point );
4007 case T_leader_length:
4023 int orientation =
parseInt(
"orthogonal dimension orientation" );
4029 orientation = std::clamp( orientation, 0, 1 );
4038 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4046 NeedSYMBOLorNUMBER();
4047 dim->SetPrefix( FromUTF8() );
4052 NeedSYMBOLorNUMBER();
4053 dim->SetSuffix( FromUTF8() );
4059 int mode =
parseInt(
"dimension units mode" );
4060 mode = std::max( 0, std::min( 4, mode ) );
4066 case T_units_format:
4068 int format =
parseInt(
"dimension units format" );
4069 format = std::clamp( format, 0, 3 );
4080 case T_override_value:
4081 NeedSYMBOLorNUMBER();
4082 dim->SetOverrideTextEnabled(
true );
4083 dim->SetOverrideText( FromUTF8() );
4087 case T_suppress_zeroes:
4092 std::cerr <<
"Unknown format token: " << GetTokenString( token ) << std::endl;
4093 Expecting(
"prefix, suffix, units, units_format, precision, override_value, "
4094 "suppress_zeroes" );
4102 isStyleKnown =
true;
4105 dim->SetKeepTextAligned(
false );
4107 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4115 dim->SetLineThickness(
parseBoardUnits(
"extension line thickness value" ) );
4119 case T_arrow_direction:
4123 if( token == T_inward )
4124 dim->ChangeArrowDirection( DIM_ARROW_DIRECTION::INWARD );
4125 else if( token == T_outward )
4126 dim->ChangeArrowDirection( DIM_ARROW_DIRECTION::OUTWARD );
4128 Expecting(
"inward or outward" );
4133 case T_arrow_length:
4139 case T_text_position_mode:
4141 int mode =
parseInt(
"text position mode" );
4142 mode = std::max( 0, std::min( 3, mode ) );
4148 case T_extension_height:
4151 wxCHECK_MSG( aligned,
nullptr, wxT(
"Invalid extension_height token" ) );
4157 case T_extension_offset:
4158 dim->SetExtensionOffset(
parseBoardUnits(
"extension offset value" ) );
4162 case T_keep_text_aligned:
4163 dim->SetKeepTextAligned(
true );
4169 wxT(
"Invalid text_frame token" ) );
4173 int textFrame =
parseInt(
"text frame mode" );
4174 textFrame = std::clamp( textFrame, 0, 3 );
4181 Expecting(
"thickness, arrow_length, arrow_direction, text_position_mode, "
4182 "extension_height, extension_offset" );
4195 if( token != T_pts )
4201 dim->SetStart( point );
4215 if( token != T_pts )
4221 dim->SetEnd( point );
4235 if( token == T_pts )
4257 if( token != T_pts )
4271 if( token != T_pts )
4285 if( token != T_pts )
4299 if( token != T_pts )
4313 dim->SetLocked( isLocked );
4318 Expecting(
"layer, tstamp, uuid, gr_text, feature1, feature2, crossbar, arrow1a, "
4319 "arrow1b, arrow2a, or arrow2b" );
4324 dim->SetLocked(
true );
4328 return dim.release();
4350 wxCHECK_MSG( CurTok() == T_module || CurTok() == T_footprint,
nullptr,
4351 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FOOTPRINT." ) );
4359 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
4361 footprint->SetInitialComments( aInitialComments );
4370 if( !IsSymbol( token ) && token != T_NUMBER )
4371 Expecting(
"symbol|number" );
4377 THROW_IO_ERROR( wxString::Format(
_(
"Invalid footprint ID in\nfile: %s\nline: %d\n"
4379 CurSource(), CurLineNumber(), CurOffset() ) );
4392 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4394 if( token == T_LEFT )
4404 int this_version =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
4408 footprint->SetFileFormatVersionAtLoad( this_version );
4419 case T_generator_version:
4466 footprint->SetPosition( pt );
4469 if( token == T_NUMBER )
4474 else if( token != T_RIGHT )
4476 Expecting( T_RIGHT );
4482 NeedSYMBOLorNUMBER();
4483 footprint->SetLibDescription( FromUTF8() );
4488 NeedSYMBOLorNUMBER();
4489 footprint->SetKeywords( FromUTF8() );
4498 wxString pName = FromUTF8();
4500 wxString pValue = FromUTF8();
4508 if( pName ==
"ki_keywords" || pName ==
"ki_locked" )
4516 if( pName ==
"ki_description" )
4524 if( pName ==
"Sheetfile" || pName ==
"Sheet file" )
4526 footprint->SetSheetfile( pValue );
4531 if( pName ==
"Sheetname" || pName ==
"Sheet name" )
4533 footprint->SetSheetname( pValue );
4541 if( pName ==
"ki_fp_filters" )
4543 footprint->SetFilters( pValue );
4561 if( footprint->HasFieldByName( pName ) )
4563 field = footprint->GetFieldByName( pName );
4568 field = footprint->AddField(
PCB_FIELD( footprint.get(), footprint->GetFieldCount(),
4590 NeedSYMBOLorNUMBER();
4591 footprint->SetPath(
KIID_PATH( FromUTF8() ) );
4597 footprint->SetSheetname( FromUTF8() );
4603 footprint->SetSheetfile( FromUTF8() );
4607 case T_autoplace_cost90:
4608 case T_autoplace_cost180:
4609 parseInt(
"legacy auto-place cost" );
4613 case T_private_layers:
4617 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4622 privateLayers.
set( it->second );
4624 Expecting(
"layer name" );
4633 footprint->SetPrivateLayers( privateLayers );
4637 case T_net_tie_pad_groups:
4638 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4639 footprint->AddNetTiePadGroup( CurStr() );
4643 case T_solder_mask_margin:
4644 footprint->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
4648 if( m_requiredVersion <= 20240201 && footprint->GetLocalSolderMaskMargin() == 0 )
4649 footprint->SetLocalSolderMaskMargin( {} );
4653 case T_solder_paste_margin:
4654 footprint->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
4658 if( m_requiredVersion <= 20240201 && footprint->GetLocalSolderPasteMargin() == 0 )
4659 footprint->SetLocalSolderPasteMargin( {} );
4663 case T_solder_paste_ratio:
4664 case T_solder_paste_margin_ratio:
4665 footprint->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
4669 if( m_requiredVersion <= 20240201 && footprint->GetLocalSolderPasteMarginRatio() == 0 )
4670 footprint->SetLocalSolderPasteMarginRatio( {} );
4675 footprint->SetLocalClearance(
parseBoardUnits(
"local clearance value" ) );
4679 if( m_requiredVersion <= 20240201 && footprint->GetLocalClearance() == 0 )
4680 footprint->SetLocalClearance( {} );
4684 case T_zone_connect:
4689 case T_thermal_width:
4697 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4705 case T_through_hole:
4717 case T_exclude_from_pos_files:
4721 case T_exclude_from_bom:
4725 case T_allow_missing_courtyard:
4733 case T_allow_soldermask_bridges:
4738 Expecting(
"through_hole, smd, virtual, board_only, exclude_from_pos_files, "
4739 "exclude_from_bom or allow_solder_mask_bridges" );
4753 switch( field->GetId() )
4757 const_cast<KIID&
>( footprint->Reference().m_Uuid ) =
text->m_Uuid;
4765 const_cast<KIID&
>( footprint->Value().m_Uuid ) =
text->m_Uuid;
4772 footprint->Add(
text, ADD_MODE::APPEND,
true );
4780 footprint->Add( textbox, ADD_MODE::APPEND,
true );
4787 footprint->Add( table, ADD_MODE::APPEND,
true );
4799 footprint->Add( shape, ADD_MODE::APPEND,
true );
4806 footprint->Add(
image, ADD_MODE::APPEND,
true );
4813 footprint->Add( dimension, ADD_MODE::APPEND,
true );
4820 footprint->Add(
pad, ADD_MODE::APPEND,
true );
4827 footprint->Add3DModel( model );
4835 footprint->Add( zone, ADD_MODE::APPEND,
true );
4843 case T_embedded_fonts:
4845 footprint->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
4850 case T_embedded_files:
4853 embeddedFilesParser.SyncLineReaderWith( *
this );
4857 embeddedFilesParser.
ParseEmbedded( footprint->GetEmbeddedFiles() );
4861 wxLogError( e.
What() );
4864 SyncLineReaderWith( embeddedFilesParser );
4868 case T_component_classes:
4870 std::unordered_set<wxString> componentClassNames;
4872 while( ( token = NextTok() ) != T_RIGHT )
4874 if( token != T_LEFT )
4875 Expecting( T_LEFT );
4877 if( ( token = NextTok() ) != T_class )
4878 Expecting( T_class );
4880 NeedSYMBOLorNUMBER();
4881 componentClassNames.insert(
From_UTF8( CurText() ) );
4889 componentClassNames );
4890 footprint->SetComponentClass( componentClass );
4897 Expecting(
"at, descr, locked, placed, tedit, tstamp, uuid, "
4898 "autoplace_cost90, autoplace_cost180, attr, clearance, "
4899 "embedded_files, fp_arc, fp_circle, fp_curve, fp_line, fp_poly, "
4900 "fp_rect, fp_text, pad, group, generator, model, path, solder_mask_margin, "
4901 "solder_paste_margin, solder_paste_margin_ratio, tags, thermal_gap, "
4902 "version, zone, zone_connect, or component_classes" );
4916 if( footprint->GetKeywords().StartsWith( wxT(
"net tie" ) ) )
4920 for(
PAD*
pad : footprint->Pads() )
4922 if( !padGroup.IsEmpty() )
4923 padGroup += wxS(
", " );
4925 padGroup +=
pad->GetNumber();
4928 if( !padGroup.IsEmpty() )
4929 footprint->AddNetTiePadGroup( padGroup );
4933 footprint->SetAttributes( attributes );
4935 footprint->SetFPID( fpid );
4937 return footprint.release();
4943 wxCHECK_MSG( CurTok() == T_pad,
nullptr,
4944 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PAD." ) );
4948 bool foundNet =
false;
4950 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
4952 NeedSYMBOLorNUMBER();
4953 pad->SetNumber( FromUTF8() );
4955 T token = NextTok();
4960 pad->SetAttribute( PAD_ATTRIB::PTH );
4969 pad->SetAttribute( PAD_ATTRIB::SMD );
4977 pad->SetAttribute( PAD_ATTRIB::CONN );
4984 case T_np_thru_hole:
4985 pad->SetAttribute( PAD_ATTRIB::NPTH );
4989 Expecting(
"thru_hole, smd, connect, or np_thru_hole" );
5023 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
5026 std::optional<EDA_ANGLE> thermalBrAngleOverride;
5028 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5030 if( token == T_locked )
5036 if( token != T_LEFT )
5037 Expecting( T_LEFT );
5053 pad->SetFPRelativePosition( pt );
5056 if( token == T_NUMBER )
5061 else if( token != T_RIGHT )
5063 Expecting(
") or angle value" );
5080 bool haveWidth =
false;
5083 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5085 if( token == T_LEFT )
5090 case T_oval:
pad->SetDrillShape( PAD_DRILL_SHAPE::OBLONG );
break;
5099 drillSize.
y = drillSize.
x;
5118 Expecting(
"oval, size, or offset" );
5126 if(
pad->GetAttribute() != PAD_ATTRIB::SMD &&
pad->GetAttribute() != PAD_ATTRIB::CONN )
5127 pad->SetDrillSize( drillSize );
5137 pad->SetLayerSet( layerMask );
5146 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d offset: %d" ),
5147 CurSource(), CurLineNumber(), CurOffset() );
5150 NeedSYMBOLorNUMBER();
5155 wxString netName( FromUTF8() );
5165 wxLogError(
_(
"Net name doesn't match ID in\nfile: %s\nline: %d offset: %d" ),
5166 CurSource(), CurLineNumber(), CurOffset() );
5174 NeedSYMBOLorNUMBER();
5175 pad->SetPinFunction( FromUTF8() );
5180 NeedSYMBOLorNUMBER();
5181 pad->SetPinType( FromUTF8() );
5190 case T_solder_mask_margin:
5191 pad->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
5195 if( m_requiredVersion <= 20240201 && pad->GetLocalSolderMaskMargin() == 0 )
5196 pad->SetLocalSolderMaskMargin( {} );
5200 case T_solder_paste_margin:
5201 pad->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
5205 if( m_requiredVersion <= 20240201 && pad->GetLocalSolderPasteMargin() == 0 )
5206 pad->SetLocalSolderPasteMargin( {} );
5210 case T_solder_paste_margin_ratio:
5211 pad->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
5215 if( m_requiredVersion <= 20240201 && pad->GetLocalSolderPasteMarginRatio() == 0 )
5216 pad->SetLocalSolderPasteMarginRatio( {} );
5225 if( m_requiredVersion <= 20240201 && pad->GetLocalClearance() == 0 )
5226 pad->SetLocalClearance( {} );
5234 case T_zone_connect:
5239 case T_thermal_width:
5240 case T_thermal_bridge_width:
5245 case T_thermal_bridge_angle:
5256 case T_roundrect_rratio:
5262 case T_chamfer_ratio:
5274 bool end_list =
false;
5294 case T_bottom_right:
5304 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
5305 "chamfer_bottom_right" );
5316 while( token != T_RIGHT )
5322 case T_pad_prop_bga:
pad->SetProperty( PAD_PROP::BGA );
break;
5323 case T_pad_prop_fiducial_glob:
pad->SetProperty( PAD_PROP::FIDUCIAL_GLBL );
break;
5324 case T_pad_prop_fiducial_loc:
pad->SetProperty( PAD_PROP::FIDUCIAL_LOCAL );
break;
5325 case T_pad_prop_testpoint:
pad->SetProperty( PAD_PROP::TESTPOINT );
break;
5326 case T_pad_prop_castellated:
pad->SetProperty( PAD_PROP::CASTELLATED );
break;
5327 case T_pad_prop_heatsink:
pad->SetProperty( PAD_PROP::HEATSINK );
break;
5328 case T_pad_prop_mechanical:
pad->SetProperty( PAD_PROP::MECHANICAL );
break;
5329 case T_none:
pad->SetProperty( PAD_PROP::NONE );
break;
5330 case T_RIGHT:
break;
5334 Expecting(
"pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc"
5335 " pad_prop_heatsink or pad_prop_castellated" );
5352 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5354 if( token == T_LEFT )
5385 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
5392 case T_remove_unused_layers:
5395 pad->SetRemoveUnconnected( remove );
5399 case T_keep_end_layers:
5402 pad->SetKeepTopBottom( keep );
5406 case T_zone_layer_connections:
5413 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5418 Expecting(
"copper layer name" );
5440 Expecting(
"at, locked, drill, layers, net, die_length, roundrect_rratio, "
5441 "solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, uuid, "
5442 "clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
5443 "pinfunction, pintype, zone_connect, thermal_width, thermal_gap, padstack or "
5451 pad->SetNetCode( 0,
true );
5454 if( thermalBrAngleOverride )
5456 pad->SetThermalSpokeAngle( *thermalBrAngleOverride );
5479 if( !
pad->CanHaveNumber() )
5483 pad->SetNumber( wxEmptyString );
5487 if(
pad->GetSizeX() <= 0 ||
pad->GetSizeY() <= 0 )
5492 wxLogWarning(
_(
"Invalid zero-sized pad pinned to %s in\nfile: %s\nline: %d\noffset: %d" ),
5493 wxT(
"1µm" ), CurSource(), CurLineNumber(), CurOffset() );
5496 return pad.release();
5503 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
5505 if( token != T_LEFT )
5506 Expecting( T_LEFT );
5561 while( (token = NextTok() ) != T_RIGHT )
5576 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
5578 if( token != T_LEFT )
5579 Expecting( T_LEFT );
5590 case T_front_inner_back:
5599 Expecting(
"front_inner_back or custom" );
5610 if( curText ==
"Inner" )
5614 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
5615 "line: %d\noffset: %d." ),
5616 CurSource(), CurLineNumber(), CurOffset() ) );
5629 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
5630 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
5634 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5636 if( token != T_LEFT )
5637 Expecting( T_LEFT );
5649 aPad->
SetShape( curLayer, PAD_SHAPE::CIRCLE );
5653 aPad->
SetShape( curLayer, PAD_SHAPE::RECTANGLE );
5657 aPad->
SetShape( curLayer, PAD_SHAPE::OVAL );
5661 aPad->
SetShape( curLayer, PAD_SHAPE::TRAPEZOID );
5667 aPad->
SetShape( curLayer, PAD_SHAPE::ROUNDRECT );
5671 aPad->
SetShape( curLayer, PAD_SHAPE::CUSTOM );
5675 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
5686 aPad->
SetSize( curLayer, sz );
5711 case T_roundrect_rratio:
5717 case T_chamfer_ratio:
5723 aPad->
SetShape( curLayer, PAD_SHAPE::CHAMFERED_RECT );
5732 bool end_list =
false;
5752 case T_bottom_right:
5762 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
5763 "chamfer_bottom_right" );
5768 aPad->
SetShape( curLayer, PAD_SHAPE::CHAMFERED_RECT );
5773 case T_thermal_bridge_width:
5784 case T_thermal_bridge_angle:
5790 case T_zone_connect:
5791 padstack.
ZoneConnection( curLayer ) = magic_enum::enum_cast<ZONE_CONNECTION>(
5792 parseInt(
"zone connection value" ) );
5808 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5810 if( token != T_LEFT )
5811 Expecting( T_LEFT );
5849 while( ( token = NextTok() ) != T_RIGHT )
5862 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5864 if( token == T_LEFT )
5895 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
5912 Expecting(
"mode or layer" );
5923 while( ( token = NextTok() ) != T_RIGHT )
5928 KIID uuid( CurStr() );
5936 wxCHECK_RET( CurTok() == T_group,
5937 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
5943 groupInfo.
parent = aParent;
5945 while( ( token = NextTok() ) != T_LEFT )
5947 if( token == T_STRING )
5948 groupInfo.
name = FromUTF8();
5949 else if( token == T_locked )
5952 Expecting(
"group name or locked" );
5955 for( ; token != T_RIGHT; token = NextTok() )
5957 if( token != T_LEFT )
5958 Expecting( T_LEFT );
5984 Expecting(
"uuid, locked, or members" );
5992 wxCHECK_RET( CurTok() == T_generated, wxT(
"Cannot parse " ) + GetTokenString( CurTok() )
5993 + wxT(
" as PCB_GENERATOR." ) );
6001 genInfo.
parent = aParent;
6008 if( token != T_uuid && token != T_id )
6009 Expecting( T_uuid );
6015 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6017 if( token != T_LEFT )
6018 Expecting( T_LEFT );
6032 genInfo.
name = FromUTF8();
6038 genInfo.
locked = token == T_yes;
6051 wxString pName = FromUTF8();
6058 genInfo.
properties.emplace( pName, wxAny(
true ) );
6064 genInfo.
properties.emplace( pName, wxAny(
false ) );
6071 genInfo.
properties.emplace( pName, wxAny( pValue ) );
6077 wxString pValue = FromUTF8();
6096 genInfo.
properties.emplace( pName, wxAny( pt ) );
6106 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6111 genInfo.
properties.emplace( pName, wxAny( chain ) );
6114 default: Expecting(
"xy or pts" );
6119 default: Expecting(
"a number, symbol, string or (" );
6131 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
6132 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ARC." ) );
6137 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board );
6139 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6142 if( token == T_locked )
6144 arc->SetLocked(
true );
6148 if( token != T_LEFT )
6149 Expecting( T_LEFT );
6158 arc->SetStart( pt );
6190 case T_solder_mask_margin:
6191 arc->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6198 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d\noffset: %d." ),
6199 CurSource(), CurLineNumber(), CurOffset() );
6222 Expecting(
"start, mid, end, width, layer, solder_mask_margin, net, tstamp, uuid, "
6227 return arc.release();
6233 wxCHECK_MSG( CurTok() == T_segment,
nullptr,
6234 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TRACK." ) );
6239 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
6241 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6244 if( token == T_locked )
6246 track->SetLocked(
true );
6250 if( token != T_LEFT )
6251 Expecting( T_LEFT );
6260 track->SetStart( pt );
6267 track->SetEnd( pt );
6285 case T_solder_mask_margin:
6286 track->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6293 wxLogError(
_(
"Invalid net ID in\nfile: '%s'\nline: %d\noffset: %d." ),
6294 CurSource(), CurLineNumber(), CurOffset() );
6317 Expecting(
"start, end, width, layer, solder_mask_margin, net, tstamp, uuid, "
6322 return track.release();
6328 wxCHECK_MSG( CurTok() == T_via,
nullptr,
6329 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_VIA." ) );
6334 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
6339 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6342 if( token == T_locked )
6344 via->SetLocked(
true );
6348 if( token == T_LEFT )
6354 via->SetViaType( VIATYPE::BLIND_BURIED );
6358 via->SetViaType( VIATYPE::MICROVIA );
6364 via->SetStart( pt );
6386 via->SetLayerPair( layer1, layer2 );
6389 Expecting(
"layer name" );
6398 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d\noffset: %d" ),
6399 CurSource(), CurLineNumber(), CurOffset() );
6405 case T_remove_unused_layers:
6408 via->SetRemoveUnconnected( remove );
6412 case T_keep_end_layers:
6415 via->SetKeepStartEnd( keep );
6419 case T_zone_layer_connections:
6429 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6434 Expecting(
"copper layer name" );
6475 Expecting(
"blind, micro, at, size, drill, layers, net, free, tstamp, uuid, status or "
6480 return via.release();
6490 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
6492 if( token == T_front )
6494 else if( token == T_back )
6496 else if( token != T_none )
6497 Expecting(
"front, back, or none" );
6509 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
6511 if( token != T_LEFT )
6512 Expecting( T_LEFT );
6523 case T_front_inner_back:
6532 Expecting(
"front_inner_back or custom" );
6543 if( curText ==
"Inner" )
6547 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
6548 "line: %d\noffset: %d." ),
6549 CurSource(), CurLineNumber(), CurOffset() ) );
6562 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
6563 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
6567 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6569 if( token != T_LEFT )
6570 Expecting( T_LEFT );
6580 padstack.
SetSize( { diameter, diameter }, curLayer );
6587 Expecting(
"size" );
6595 Expecting(
"mode or layer" );
6604 wxCHECK_MSG( CurTok() == T_zone,
nullptr,
6605 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ZONE." ) );
6612 wxString netnameFromfile;
6615 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
6616 std::map<PCB_LAYER_ID, std::vector<SEG>> legacySegs;
6618 bool addedFilledPolygons =
false;
6619 bool isStrokedFill =
true;
6621 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aParent );
6623 zone->SetAssignedPriority( 0 );
6626 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::ALWAYS );
6628 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6631 if( token == T_locked )
6633 zone->SetLocked(
true );
6637 if( token == T_LEFT )
6651 if( !zone->SetNetCode( tmp,
true ) )
6653 wxLogError(
_(
"Invalid net ID in\nfile: %s;\nline: %d\noffset: %d." ),
6654 CurSource(), CurLineNumber(), CurOffset() );
6661 NeedSYMBOLorNUMBER();
6662 netnameFromfile = FromUTF8();
6685 if( token != T_none && token != T_edge && token != T_full )
6686 Expecting(
"none, edge, or full" );
6691 case T_none: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH;
break;
6692 case T_edge: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE;
break;
6693 case T_full: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL;
break;
6701 zone->SetAssignedPriority(
parseInt(
"zone priority" ) );
6705 case T_connect_pads:
6706 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6708 if( token == T_LEFT )
6714 zone->SetPadConnection( ZONE_CONNECTION::FULL );
6718 zone->SetPadConnection( ZONE_CONNECTION::NONE );
6721 case T_thru_hole_only:
6722 zone->SetPadConnection( ZONE_CONNECTION::THT_THERMAL );
6731 Expecting(
"yes, no, or clearance" );
6737 case T_min_thickness:
6742 case T_filled_areas_thickness:
6749 isStrokedFill =
false;
6755 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6757 if( token == T_LEFT )
6763 zone->SetIsFilled(
true );
6769 if( token != T_segment && token != T_hatch && token != T_polygon )
6770 Expecting(
"segment, hatch or polygon" );
6775 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
6781 zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
6788 case T_hatch_thickness:
6798 case T_hatch_orientation:
6801 zone->SetHatchOrientation( orientation );
6806 case T_hatch_smoothing_level:
6807 zone->SetHatchSmoothingLevel(
parseDouble( T_hatch_smoothing_level ) );
6811 case T_hatch_smoothing_value:
6812 zone->SetHatchSmoothingValue(
parseDouble( T_hatch_smoothing_value ) );
6816 case T_hatch_border_algorithm:
6819 if( token != T_hatch_thickness && token != T_min_thickness )
6820 Expecting(
"hatch_thickness or min_thickness" );
6822 zone->SetHatchBorderAlgorithm( token == T_hatch_thickness ? 1 : 0 );
6826 case T_hatch_min_hole_area:
6827 zone->SetHatchHoleMinArea(
parseDouble( T_hatch_min_hole_area ) );
6831 case T_arc_segments:
6841 case T_thermal_bridge_width:
6842 zone->SetThermalReliefSpokeWidth(
parseBoardUnits( T_thermal_bridge_width ) );
6854 if( !zone->GetIsRuleArea() )
6860 if( !zone->GetIsRuleArea() )
6866 Expecting(
"none, chamfer, or fillet" );
6875 if( !zone->GetIsRuleArea() )
6876 zone->SetCornerRadius( tmp );
6881 case T_island_removal_mode:
6882 tmp =
parseInt(
"island_removal_mode" );
6884 if( tmp >= 0 && tmp <= 2 )
6890 case T_island_area_min:
6899 Expecting(
"mode, arc_segments, thermal_gap, thermal_bridge_width, "
6900 "hatch_thickness, hatch_gap, hatch_orientation, "
6901 "hatch_smoothing_level, hatch_smoothing_value, "
6902 "hatch_border_algorithm, hatch_min_hole_area, smoothing, radius, "
6903 "island_removal_mode, or island_area_min" );
6910 zone->SetIsRuleArea(
true );
6912 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6914 if( token == T_LEFT )
6921 zone->SetRuleAreaPlacementSourceType(
6922 RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME );
6924 zone->SetRuleAreaPlacementSource( FromUTF8() );
6927 case T_component_class:
6929 zone->SetRuleAreaPlacementSourceType(
6930 RULE_AREA_PLACEMENT_SOURCE_TYPE::COMPONENT_CLASS );
6932 zone->SetRuleAreaPlacementSource( FromUTF8() );
6939 if( token == T_yes )
6940 zone->SetRuleAreaPlacementEnabled(
true );
6941 else if( token == T_no )
6942 zone->SetRuleAreaPlacementEnabled(
false );
6944 Expecting(
"yes or no" );
6950 Expecting(
"enabled, sheetname or component_class" );
6962 zone->SetIsRuleArea(
true );
6965 zone->SetDoNotAllowPads(
false );
6966 zone->SetDoNotAllowFootprints(
false );
6968 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6970 if( token == T_LEFT )
6978 if( token != T_allowed && token != T_not_allowed )
6979 Expecting(
"allowed or not_allowed" );
6981 zone->SetDoNotAllowTracks( token == T_not_allowed );
6987 if( token != T_allowed && token != T_not_allowed )
6988 Expecting(
"allowed or not_allowed" );
6990 zone->SetDoNotAllowVias( token == T_not_allowed );
6996 if( token != T_allowed && token != T_not_allowed )
6997 Expecting(
"allowed or not_allowed" );
6999 zone->SetDoNotAllowCopperPour( token == T_not_allowed );
7005 if( token != T_allowed && token != T_not_allowed )
7006 Expecting(
"allowed or not_allowed" );
7008 zone->SetDoNotAllowPads( token == T_not_allowed );
7014 if( token != T_allowed && token != T_not_allowed )
7015 Expecting(
"allowed or not_allowed" );
7017 zone->SetDoNotAllowFootprints( token == T_not_allowed );
7021 Expecting(
"tracks, vias or copperpour" );
7036 if( token != T_pts )
7039 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7048 zone->AddPolygon( outline );
7052 case T_filled_polygon:
7058 if( token == T_layer )
7064 if( token != T_LEFT )
7065 Expecting( T_LEFT );
7072 filledLayer = zone->GetFirstLayer();
7075 bool island =
false;
7077 if( token == T_island )
7085 if( token != T_pts )
7088 if( !pts.count( filledLayer ) )
7097 zone->SetIsIsland( filledLayer, idx );
7099 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7104 addedFilledPolygons |= !poly.
IsEmpty();
7109 case T_fill_segments:
7113 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7115 if( token != T_LEFT )
7116 Expecting( T_LEFT );
7120 if( token != T_pts )
7124 filledLayer = zone->GetFirstLayer();
7131 legacySegs[filledLayer].push_back( fillSegment );
7141 zone->SetZoneName( FromUTF8() );
7146 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7148 if( token == T_LEFT )
7154 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7156 if( token == T_LEFT )
7164 if( token == T_padvia )
7165 zone->SetTeardropAreaType( TEARDROP_TYPE::TD_VIAPAD );
7166 else if( token == T_track_end )
7167 zone->SetTeardropAreaType( TEARDROP_TYPE::TD_TRACKEND );
7169 Expecting(
"padvia or track_end" );
7175 Expecting(
"type" );
7182 Expecting(
"teardrop" );
7193 Expecting(
"net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
7194 "fill, polygon, filled_polygon, fill_segments, attr, locked, uuid, or name" );
7198 if( zone->GetNumCorners() > 2 )
7200 if( !zone->IsOnCopperLayer() )
7207 zone->SetBorderDisplayStyle( hatchStyle, hatchPitch,
true );
7210 if( addedFilledPolygons )
7212 if( isStrokedFill && !zone->GetIsRuleArea() )
7217 _(
"Legacy zone fill strategy is not supported anymore.\nZone fills will "
7218 "be converted on best-effort basis." ) );
7223 if( zone->GetMinThickness() > 0 )
7225 for(
auto& [layer, polyset] : pts )
7227 polyset.InflateWithLinkedHoles( zone->GetMinThickness() / 2,
7228 CORNER_STRATEGY::ROUND_ALL_CORNERS,
7235 for(
auto& [layer, polyset] : pts )
7236 zone->SetFilledPolysList( layer, polyset );
7238 zone->CalculateFilledArea();
7240 else if( legacySegs.size() > 0 )
7248 wxLogWarning(
_(
"The legacy segment zone fill mode is no longer supported.\n"
7249 "Zone fills will be converted on a best-effort basis." ) );
7255 for(
const auto& [layer, segments] : legacySegs )
7259 if( zone->HasFilledPolysForLayer( layer ) )
7262 for(
const auto& seg : segments )
7273 zone->SetFilledPolysList( layer, layerFill );
7274 zone->CalculateFilledArea();
7282 bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsRuleArea();
7289 && ( !zone->GetNet() || zone->GetNet()->GetNetname() != netnameFromfile ) )
7318 zone->SetNeedRefill(
false );
7320 return zone.release();
7326 wxCHECK_MSG( CurTok() == T_target,
nullptr,
7327 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TARGET." ) );
7332 std::unique_ptr<PCB_TARGET> target = std::make_unique<PCB_TARGET>(
nullptr );
7334 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7336 if( token == T_LEFT )
7342 target->SetShape( 1 );
7346 target->SetShape( 0 );
7352 target->SetPosition( pt );
7379 Expecting(
"x, plus, at, size, width, layer, uuid, or tstamp" );
7383 return target.release();
7405 std::string idStr( CurStr() );
7408 if( *idStr.begin() ==
'"' && *idStr.rbegin() ==
'"' )
7409 idStr = idStr.substr( 1, idStr.length() - 1 );
7418 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.