71#include <wx/mstream.h>
80constexpr double INT_LIMIT = std::numeric_limits<int>::max() - 10;
82using namespace PCB_KEYS_T;
122 for(
int i=1; i<=14; ++i )
124 std::string key =
StrPrintf(
"Inner%d.Cu", i );
135 TIME_PT curTime = CLOCK::now();
136 unsigned curLine = reader->LineNumber();
139 if(
delta > std::chrono::milliseconds( 250 ) )
158 while( ( token = NextTok() ) != T_EOF )
160 if( token == T_LEFT )
163 if( token == T_RIGHT )
180 m_netCodes.resize(
static_cast<std::size_t
>( aIndex ) + 1 );
220 else if( token == T_no )
223 Expecting(
"yes or no" );
231 int year, month, day;
240 if( day <= 0 || month <= 0 || month > 12 ||
241 day > wxDateTime::GetNumberOfDays( (wxDateTime::Month)( month - 1 ), year ) )
248 wxDateTime date( day, (wxDateTime::Month)( month - 1 ), year, 0, 0, 0, 0 );
249 return date.FormatDate();
255 if( CurTok() != T_LEFT )
275 if( CurTok() != T_LEFT )
294 bool has_start =
false;
295 bool has_mid =
false;
296 bool has_end =
false;
298 VECTOR2I arc_start, arc_mid, arc_end;
300 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
302 if( token != T_LEFT )
328 Expecting(
"start, mid or end" );
335 Expecting(
"start" );
343 SHAPE_ARC arc( arc_start, arc_mid, arc_end, 0 );
347 if( token != T_RIGHT )
348 Expecting( T_RIGHT );
353 Expecting(
"xy or arc" );
381 return { pName, pValue };
391 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
393 if( token == T_LEFT )
402 case T_allow_two_segments:
406 case T_prefer_zone_connections:
410 case T_best_length_ratio:
420 case T_best_width_ratio:
441 Expecting(
"enabled, allow_two_segments, prefer_zone_connections, best_length_ratio, "
442 "max_length, best_width_ratio, max_width, curve_points or filter_ratio" );
450 wxCHECK_RET( CurTok() == T_effects,
451 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as EDA_TEXT." ) );
466 bool foundTextSize =
false;
469 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
471 if( token == T_LEFT )
477 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
479 if( token == T_LEFT )
486 faceName = FromUTF8();
498 foundTextSize =
true;
521 Expecting(
"face, size, line_spacing, thickness, bold, or italic" );
525 if( !faceName.IsEmpty() )
534 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
536 if( token == T_LEFT )
562 Expecting(
"left, right, top, bottom, or mirror" );
574 Expecting(
"font, justify, or hide" );
593 NeedSYMBOLorNUMBER();
594 wxString cacheText =
From_UTF8( CurText() );
597 text->SetupRenderCache( cacheText, cacheAngle );
599 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
601 if( token != T_LEFT )
606 if( token != T_polygon )
607 Expecting( T_polygon );
611 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
613 if( token != T_LEFT )
623 while( (token = NextTok() ) != T_RIGHT )
634 text->AddRenderCacheGlyph( poly );
641 wxCHECK_MSG( CurTok() == T_model,
nullptr,
642 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FP_3DMODEL." ) );
647 NeedSYMBOLorNUMBER();
650 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
652 if( token == T_LEFT )
736 Expecting(
"at, hide, opacity, offset, scale, or rotate" );
755 if( CurTok() != T_LEFT )
758 if( NextTok() != T_kicad_pcb)
776 std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
783 if( token != T_LEFT )
805 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
834 std::map<wxString, wxString> properties;
838 std::vector<BOARD_ITEM*> bulkAddedItems;
841 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
845 if( token != T_LEFT )
912 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
913 bulkAddedItems.push_back( item );
918 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
919 bulkAddedItems.push_back( item );
924 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
925 bulkAddedItems.push_back( item );
930 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
931 bulkAddedItems.push_back( item );
936 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
937 bulkAddedItems.push_back( item );
943 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
944 bulkAddedItems.push_back( item );
949 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
950 bulkAddedItems.push_back( item );
955 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
956 bulkAddedItems.push_back( item );
965 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
966 bulkAddedItems.push_back( item );
971 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
972 bulkAddedItems.push_back( item );
977 m_board->
Add( item, ADD_MODE::BULK_APPEND,
true );
978 bulkAddedItems.push_back( item );
983 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
988 if( bulkAddedItems.size() > 0 )
996 wxString msg, undefinedLayerNames, destLayerName;
1000 if( !undefinedLayerNames.IsEmpty() )
1001 undefinedLayerNames += wxT(
", " );
1003 undefinedLayerNames += layerName;
1010 msg.Printf(
_(
"Items found on undefined layers (%s).\n"
1011 "Do you wish to rescue them to the %s layer?" ),
1012 undefinedLayerNames,
1021 auto visitItem = [&](
BOARD_ITEM* curr_item )
1023 if( curr_item->GetLayer() ==
Rescue )
1024 curr_item->SetLayer( destLayer );
1034 if(
via->GetViaType() == VIATYPE::THROUGH )
1037 via->LayerPair( &top_layer, &bottom_layer );
1041 if( top_layer ==
Rescue )
1044 if( bottom_layer ==
Rescue )
1045 bottom_layer =
B_Cu;
1047 via->SetLayerPair( top_layer, bottom_layer );
1060 visitItem( drawing );
1064 for(
BOARD_ITEM* drawing : fp->GraphicalItems() )
1065 visitItem( drawing );
1075 THROW_IO_ERROR( wxT(
"One or more undefined undefinedLayerNames was found; "
1076 "open the board in the PCB Editor to resolve." ) );
1086 auto getItem = [&](
const KIID& aId )
1090 if(
dynamic_cast<BOARD*
>( aParent ) )
1092 aItem =
static_cast<BOARD*
>( aParent )->GetItem( aId );
1096 static_cast<FOOTPRINT*
>( aParent )->RunOnChildren(
1099 if( child->
m_Uuid == aId )
1116 group->SetName( groupInfo.name );
1117 const_cast<KIID&
>(
group->m_Uuid ) = groupInfo.uuid;
1119 if( groupInfo.locked )
1120 group->SetLocked(
true );
1123 static_cast<FOOTPRINT*
>( groupInfo.parent )->
Add(
group, ADD_MODE::INSERT,
true );
1125 static_cast<BOARD*
>( groupInfo.parent )->Add(
group, ADD_MODE::INSERT,
true );
1134 for(
const KIID& aUuid : groupInfo.memberUuids )
1141 item = getItem( aUuid );
1153 group->AddItem( item );
1166 wxCHECK_RET( CurTok() == T_kicad_pcb,
1167 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
1173 if( tok == T_version )
1192 wxCHECK_RET( CurTok() == T_general,
1193 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) +
1194 wxT(
" as a general section." ) );
1198 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1200 if( token != T_LEFT )
1201 Expecting( T_LEFT );
1212 case T_legacy_teardrops:
1218 while( ( token = NextTok() ) != T_RIGHT )
1220 if( !IsSymbol( token ) && token != T_NUMBER )
1221 Expecting(
"symbol or number" );
1230 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200119 ) || CurTok() == T_paper,
1231 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
1238 wxString pageType = FromUTF8();
1240 if( !pageInfo.
SetType( pageType ) )
1243 err.Printf(
_(
"Page type '%s' is not valid." ), FromUTF8() );
1251 const double Mils2mm = 0.0254;
1272 if( token == T_portrait )
1277 else if( token != T_RIGHT )
1279 Expecting(
"portrait|)" );
1288 wxCHECK_RET( CurTok() == T_title_block,
1289 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as TITLE_BLOCK." ) );
1294 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1296 if( token != T_LEFT )
1297 Expecting( T_LEFT );
1310 titleBlock.
SetDate( FromUTF8() );
1325 int commentNumber =
parseInt(
"comment" );
1327 switch( commentNumber )
1376 err.Printf( wxT(
"%d is not a valid title block comment number" ), commentNumber );
1384 Expecting(
"title, date, rev, company, or comment" );
1399 std::string userName;
1401 bool isVisible =
true;
1405 if( CurTok() != T_LEFT )
1406 Expecting( T_LEFT );
1409 int layer_num =
parseInt(
"layer index" );
1411 NeedSYMBOLorNUMBER();
1420 if( token == T_hide )
1425 else if( token == T_STRING )
1427 userName = CurText();
1430 else if( token != T_RIGHT )
1432 Expecting(
"hide, user defined name, or )" );
1440 if( !userName.empty() )
1455 int dielectric_idx = 1;
1458 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1460 if( CurTok() != T_LEFT )
1461 Expecting( T_LEFT );
1465 if( token != T_layer )
1469 case T_copper_finish:
1475 case T_edge_plating:
1481 case T_dielectric_constraints:
1487 case T_edge_connector:
1491 if( token == T_yes )
1493 else if( token == T_bevelled )
1499 case T_castellated_pads:
1533 else if( layerId >=
F_Cu && layerId <=
B_Cu )
1546 stackup.
Add( item );
1550 Expecting(
"layer_name" );
1553 bool has_next_sublayer =
true;
1554 int sublayer_idx = 0;
1557 while( has_next_sublayer )
1559 has_next_sublayer =
false;
1561 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1563 if( token == T_addsublayer )
1565 has_next_sublayer =
true;
1569 if( token == T_LEFT )
1585 if( token == T_LEFT )
1588 if( token == T_locked )
1611 case T_loss_tangent:
1631 wxColour wx_color =
color.ToColour();
1634 name.Printf( wxT(
"#%02X%02X%02X%02X" ),
1654 if( has_next_sublayer )
1662 if( token != T_RIGHT )
1679 aMap[
"Adesivo.Retro"] =
"B.Adhes";
1680 aMap[
"Adesivo.Fronte"] =
"F.Adhes";
1681 aMap[
"Pasta.Retro"] =
"B.Paste";
1682 aMap[
"Pasta.Fronte"] =
"F.Paste";
1683 aMap[
"Serigrafia.Retro"] =
"B.SilkS";
1684 aMap[
"Serigrafia.Fronte"] =
"F.SilkS";
1685 aMap[
"Maschera.Retro"] =
"B.Mask";
1686 aMap[
"Maschera.Fronte"] =
"F.Mask";
1687 aMap[
"Grafica"] =
"Dwgs.User";
1688 aMap[
"Commenti"] =
"Cmts.User";
1689 aMap[
"Eco1"] =
"Eco1.User";
1690 aMap[
"Eco2"] =
"Eco2.User";
1691 aMap[
"Contorno.scheda"] =
"Edge.Cuts";
1694 aMap[
"Kleju_Dolna"] =
"B.Adhes";
1695 aMap[
"Kleju_Gorna"] =
"F.Adhes";
1696 aMap[
"Pasty_Dolna"] =
"B.Paste";
1697 aMap[
"Pasty_Gorna"] =
"F.Paste";
1698 aMap[
"Opisowa_Dolna"] =
"B.SilkS";
1699 aMap[
"Opisowa_Gorna"] =
"F.SilkS";
1700 aMap[
"Maski_Dolna"] =
"B.Mask";
1701 aMap[
"Maski_Gorna"] =
"F.Mask";
1702 aMap[
"Rysunkowa"] =
"Dwgs.User";
1703 aMap[
"Komentarzy"] =
"Cmts.User";
1704 aMap[
"ECO1"] =
"Eco1.User";
1705 aMap[
"ECO2"] =
"Eco2.User";
1706 aMap[
"Krawedziowa"] =
"Edge.Cuts";
1709 aMap[
"Dessous.Adhes"] =
"B.Adhes";
1710 aMap[
"Dessus.Adhes"] =
"F.Adhes";
1711 aMap[
"Dessous.Pate"] =
"B.Paste";
1712 aMap[
"Dessus.Pate"] =
"F.Paste";
1713 aMap[
"Dessous.SilkS"] =
"B.SilkS";
1714 aMap[
"Dessus.SilkS"] =
"F.SilkS";
1715 aMap[
"Dessous.Masque"] =
"B.Mask";
1716 aMap[
"Dessus.Masque"] =
"F.Mask";
1717 aMap[
"Dessin.User"] =
"Dwgs.User";
1718 aMap[
"Contours.Ci"] =
"Edge.Cuts";
1724 wxCHECK_RET( CurTok() == T_layers,
1725 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layers." ) );
1730 int copperLayerCount = 0;
1732 bool anyHidden =
false;
1734 std::unordered_map< std::string, std::string > v3_layer_names;
1735 std::vector<LAYER> cu;
1739 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1746 cu.push_back( layer );
1759 cu[cu.size()-1].m_number =
B_Cu;
1761 for(
unsigned i=0; i < cu.size()-1; ++i )
1766 for( std::vector<LAYER>::const_iterator it = cu.begin(); it<cu.end(); ++it )
1768 enabledLayers.set( it->m_number );
1771 visibleLayers.set( it->m_number );
1783 copperLayerCount = cu.size();
1787 while( token != T_RIGHT )
1793 auto new_layer_it = v3_layer_names.find( layer.
m_name.ToStdString() );
1795 if( new_layer_it != v3_layer_names.end() )
1801 error.Printf(
_(
"Layer '%s' in file '%s' at line %d is not in fixed layer hash." ),
1814 layer.
m_name = it->first;
1818 enabledLayers.set( layer.
m_number );
1821 visibleLayers.set( layer.
m_number );
1829 if( token != T_LEFT )
1836 if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
1838 wxString err = wxString::Format(
_(
"%d is not a valid layer count" ), copperLayerCount );
1853template<
class T,
class M>
1857 typename M::const_iterator it = aMap.find( curText );
1859 if( it == aMap.end() )
1866 if( it->second ==
Rescue )
1876 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layer." ) );
1890 wxCHECK_MSG( CurTok() == T_layers,
LSET(),
1891 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as item layers." ) );
1895 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
1907 wxCHECK_RET( CurTok() == T_setup,
1908 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as setup." ) );
1911 std::shared_ptr<NETCLASS>& defaultNetClass = bds.
m_NetSettings->m_DefaultNetClass;
1918 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
1920 if( token != T_LEFT )
1921 Expecting( T_LEFT );
1931 case T_last_trace_width:
1936 case T_user_trace_width:
1952 case T_trace_clearance:
1953 defaultNetClass->SetClearance(
parseBoardUnits( T_trace_clearance ) );
1958 case T_zone_clearance:
1964 case T_zone_45_only:
1970 case T_clearance_min:
1994 case T_via_min_annulus:
2000 case T_via_min_size:
2006 case T_through_hole_min:
2013 case T_via_min_drill:
2019 case T_hole_to_hole_min:
2055 case T_uvias_allowed:
2061 case T_blind_buried_vias_allowed:
2067 case T_uvia_min_size:
2073 case T_uvia_min_drill:
2079 case T_user_diff_pair:
2094 case T_segment_width:
2106 case T_mod_edge_width:
2112 case T_pcb_text_width:
2118 case T_mod_text_width:
2124 case T_pcb_text_size:
2131 case T_mod_text_size:
2163 case T_pad_to_mask_clearance:
2168 case T_solder_mask_min_width:
2173 case T_pad_to_paste_clearance:
2178 case T_pad_to_paste_clearance_ratio:
2183 case T_allow_soldermask_bridges_in_footprints:
2188 case T_aux_axis_origin:
2212 case T_visible_elements:
2219 for(
size_t i = 0; i <
sizeof( int ) * CHAR_BIT; i++ )
2232 case T_filled_areas_thickness:
2238 case T_pcbplotparams:
2244 parser.SyncLineReaderWith( *
this );
2246 plotParams.
Parse( &parser );
2247 SyncLineReaderWith( parser );
2254 Unexpected( CurText() );
2264 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2266 if( token != T_LEFT )
2267 Expecting( T_LEFT );
2273 case T_edge_clearance:
2279 case T_copper_line_width:
2284 case T_copper_text_dims:
2288 case T_courtyard_line_width:
2293 case T_edge_cuts_line_width:
2298 case T_silk_line_width:
2303 case T_silk_text_dims:
2307 case T_fab_layers_line_width:
2312 case T_fab_layers_text_dims:
2316 case T_other_layers_line_width:
2321 case T_other_layers_text_dims:
2325 case T_dimension_units:
2331 case T_dimension_precision:
2338 Unexpected( CurText() );
2348 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2350 if( token == T_LEFT )
2370 case T_keep_upright:
2375 Expecting(
"size, thickness, italic or keep_upright" );
2383 wxCHECK_RET( CurTok() == T_net,
2384 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net." ) );
2386 int netCode =
parseInt(
"net number" );
2388 NeedSYMBOLorNUMBER();
2389 wxString
name = FromUTF8();
2414 wxCHECK_RET( CurTok() == T_net_class,
2415 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net class." ) );
2419 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( wxEmptyString );
2422 NeedSYMBOLorNUMBER();
2423 nc->SetName( FromUTF8() );
2425 nc->SetDescription( FromUTF8() );
2427 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2429 if( token != T_LEFT )
2430 Expecting( T_LEFT );
2460 case T_diff_pair_width:
2464 case T_diff_pair_gap:
2470 NeedSYMBOLorNUMBER();
2472 wxString netName = FromUTF8();
2481 std::make_unique<EDA_COMBINED_MATCHER>( netName,
CTX_NETCLASS ),
2489 Expecting(
"clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, "
2490 "diff_pair_width, diff_pair_gap or add_net" );
2498 if( netSettings->m_NetClasses.count( nc->GetName() ) )
2503 error.Printf(
_(
"Duplicate NETCLASS name '%s' in file '%s' at line %d, offset %d." ),
2504 nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(),
2508 else if( nc->GetName() == netSettings->m_DefaultNetClass->GetName() )
2510 netSettings->m_DefaultNetClass = nc;
2514 netSettings->m_NetClasses[ nc->GetName() ] = nc;
2521 wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
2522 CurTok() == T_fp_rect || CurTok() == T_fp_line || CurTok() == T_fp_poly ||
2523 CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
2524 CurTok() == T_gr_rect || CurTok() == T_gr_bbox || CurTok() == T_gr_line ||
2525 CurTok() == T_gr_poly || CurTok() == T_gr_vector,
nullptr,
2526 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_SHAPE." ) );
2531 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aParent );
2537 shape->SetShape( SHAPE_T::ARC );
2540 if( token == T_locked )
2542 shape->SetLocked(
true );
2546 if( token != T_LEFT )
2547 Expecting( T_LEFT );
2554 if( token != T_start )
2555 Expecting( T_start );
2559 shape->SetCenter( pt );
2565 if( token != T_end )
2570 shape->SetStart( pt );
2575 if( token != T_angle )
2576 Expecting( T_angle );
2583 VECTOR2I arc_start, arc_mid, arc_end;
2585 if( token != T_start )
2586 Expecting( T_start );
2594 if( token != T_mid )
2603 if( token != T_end )
2610 shape->SetArcGeometry( arc_start, arc_mid, arc_end );
2617 shape->SetShape( SHAPE_T::CIRCLE );
2620 if( token == T_locked )
2622 shape->SetLocked(
true );
2626 if( token != T_LEFT )
2627 Expecting( T_LEFT );
2631 if( token != T_center )
2632 Expecting( T_center );
2636 shape->SetStart( pt );
2642 if( token != T_end )
2647 shape->SetEnd( pt );
2653 shape->SetShape( SHAPE_T::BEZIER );
2656 if( token == T_locked )
2658 shape->SetLocked(
true );
2662 if( token != T_LEFT )
2663 Expecting( T_LEFT );
2667 if( token != T_pts )
2671 shape->SetBezierC1(
parseXY());
2672 shape->SetBezierC2(
parseXY());
2680 shape->SetShape( SHAPE_T::RECTANGLE );
2683 if( token == T_locked )
2685 shape->SetLocked(
true );
2689 if( token != T_LEFT )
2690 Expecting( T_LEFT );
2694 if( token != T_start )
2695 Expecting( T_start );
2699 shape->SetStart( pt );
2704 if( token != T_end )
2709 shape->SetEnd( pt );
2719 shape->NormalizeRect();
2731 if( token == T_locked )
2733 shape->SetLocked(
true );
2737 if( token != T_LEFT )
2738 Expecting( T_LEFT );
2742 if( token != T_start )
2743 Expecting( T_start );
2747 shape->SetStart( pt );
2752 if( token != T_end )
2757 shape->SetEnd( pt );
2764 shape->SetShape( SHAPE_T::POLY );
2765 shape->SetPolyPoints( {} );
2771 if( token == T_locked )
2773 shape->SetLocked(
true );
2777 if( token != T_LEFT )
2778 Expecting( T_LEFT );
2782 if( token != T_pts )
2785 while( (token = NextTok() ) != T_RIGHT )
2792 Expecting(
"gr_arc, gr_circle, gr_curve, gr_line, gr_poly, gr_rect or gr_bbox" );
2795 bool foundFill =
false;
2797 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2799 if( token != T_LEFT )
2800 Expecting( T_LEFT );
2824 strokeParser.SyncLineReaderWith( *
this );
2827 SyncLineReaderWith( strokeParser );
2840 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2842 if( token == T_LEFT )
2851 shape->SetFilled(
true );
2855 shape->SetFilled(
false );
2859 Expecting(
"yes, none, solid" );
2873 shape->SetLocked(
true );
2880 wxLogError(
_(
"Invalid net ID in\nfile: '%s'\nline: %d\noffset: %d." ),
2881 CurSource(), CurLineNumber(), CurOffset() );
2887 Expecting(
"layer, width, fill, tstamp, locked, net or status" );
2896 && ( shape->GetShape() == SHAPE_T::RECTANGLE || shape->GetShape() == SHAPE_T::CIRCLE ) )
2898 shape->SetFilled(
true );
2900 else if( shape->GetShape() == SHAPE_T::POLY && shape->GetLayer() !=
Edge_Cuts )
2903 shape->SetFilled(
true );
2909 if( stroke.
GetWidth() <= 0 && !shape->IsFilled() )
2914 shape->SetStroke( stroke );
2918 shape->Rotate( { 0, 0 }, parentFP->GetOrientation() );
2919 shape->Move( parentFP->GetPosition() );
2922 return shape.release();
2928 wxCHECK_MSG( CurTok() == T_image,
nullptr,
2929 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as an image." ) );
2932 std::unique_ptr<PCB_BITMAP> bitmap = std::make_unique<PCB_BITMAP>( aParent );
2934 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2936 if( token != T_LEFT )
2937 Expecting( T_LEFT );
2948 bitmap->SetPosition( pos );
2959 bitmap->SetImageScale(
parseDouble(
"image scale factor" ) );
2961 if( !std::isnormal( bitmap->GetImage()->GetScale() ) )
2962 bitmap->SetImageScale( 1.0 );
2975 data.reserve( 1 << 19 );
2977 while( token != T_RIGHT )
2979 if( !IsSymbol( token ) )
2980 Expecting(
"base64 image data" );
2986 wxMemoryBuffer buffer = wxBase64Decode( data );
2988 if( !bitmap->ReadImageFile( buffer ) )
2995 Expecting(
"at, layer, scale, data" );
2999 return bitmap.release();
3005 wxCHECK_MSG( CurTok() == T_gr_text || CurTok() == T_fp_text,
nullptr,
3006 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXT." ) );
3009 std::unique_ptr<PCB_TEXT>
text;
3011 T token = NextTok();
3019 case T_value:
text = std::make_unique<PCB_FIELD>( parentFP,
VALUE_FIELD );
break;
3021 case T_user:
text = std::make_unique<PCB_TEXT>( parentFP );
break;
3024 THROW_IO_ERROR( wxString::Format(
_(
"Cannot handle footprint text type %s" ),
3032 text = std::make_unique<PCB_TEXT>( aParent );
3035 if( token == T_locked )
3037 text->SetLocked(
true );
3041 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
3042 Expecting(
"text value" );
3044 wxString value = FromUTF8();
3045 value.Replace( wxT(
"%V" ), wxT(
"${VALUE}" ) );
3046 value.Replace( wxT(
"%R" ), wxT(
"${REFERENCE}" ) );
3047 text->SetText( value );
3053 return text.release();
3060 bool hasAngle =
false;
3067 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
3069 if( token == T_LEFT )
3083 if( CurTok() == T_NUMBER )
3090 if( parentFP && CurTok() == T_unlocked )
3107 if( token == T_knockout )
3128 Expecting(
"layer, effects, locked, render_cache or tstamp" );
3136 case T_render_cache:
3142 Expecting(
"layer, hide, effects, locked, render_cache or tstamp" );
3144 Expecting(
"layer, effects, locked, render_cache or tstamp" );
3167 wxCHECK_MSG( CurTok() == T_gr_text_box || CurTok() == T_fp_text_box,
nullptr,
3168 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXTBOX." ) );
3170 std::unique_ptr<PCB_TEXTBOX> textbox = std::make_unique<PCB_TEXTBOX>( aParent );
3173 T token = NextTok();
3175 if( token == T_locked )
3177 textbox->SetLocked(
true );
3181 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
3182 Expecting(
"text value" );
3184 textbox->SetText( FromUTF8() );
3189 if( token == T_start )
3193 textbox->SetStart(
VECTOR2I( x, y ) );
3199 if( token != T_end )
3204 textbox->SetEnd(
VECTOR2I( x, y ) );
3207 else if( token == T_pts )
3209 textbox->SetShape( SHAPE_T::POLY );
3210 textbox->GetPolyShape().RemoveAllContours();
3211 textbox->GetPolyShape().NewOutline();
3213 while( (token = NextTok() ) != T_RIGHT )
3218 Expecting(
"start or pts" );
3221 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3223 if( token != T_LEFT )
3224 Expecting( T_LEFT );
3240 strokeParser.SyncLineReaderWith( *
this );
3243 SyncLineReaderWith( strokeParser );
3248 textbox->SetBorderEnabled(
parseBool() );
3267 case T_render_cache:
3272 Expecting(
"angle, width, layer, effects, render_cache or tstamp" );
3276 textbox->SetStroke( stroke );
3279 textbox->SetBorderEnabled( stroke.
GetWidth() >= 0 );
3284 textbox->Rotate( { 0, 0 }, parentFP->GetOrientation() );
3285 textbox->Move( parentFP->GetPosition() );
3288 return textbox.release();
3294 wxCHECK_MSG( CurTok() == T_dimension,
nullptr,
3295 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as DIMENSION." ) );
3299 std::unique_ptr<PCB_DIMENSION_BASE> dim;
3303 if( token == T_locked )
3310 if( token != T_LEFT )
3315 bool isLegacyDimension =
false;
3318 if( token == T_width )
3320 isLegacyDimension =
true;
3321 dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
3327 if( token != T_type )
3328 Expecting( T_type );
3332 case T_aligned: dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
break;
3333 case T_orthogonal: dim = std::make_unique<PCB_DIM_ORTHOGONAL>( aParent );
break;
3334 case T_leader: dim = std::make_unique<PCB_DIM_LEADER>( aParent );
break;
3335 case T_center: dim = std::make_unique<PCB_DIM_CENTER>( aParent );
break;
3336 case T_radial: dim = std::make_unique<PCB_DIM_RADIAL>( aParent );
break;
3337 default: wxFAIL_MSG( wxT(
"Cannot parse unknown dimension type " )
3338 + GetTokenString( CurTok() ) );
3344 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3346 if( token != T_LEFT )
3347 Expecting( T_LEFT );
3368 dim->EDA_TEXT::operator=( *text );
3371 dim->SetTextPos(
text->GetTextPos() );
3373 if( isLegacyDimension )
3375 EDA_UNITS units = EDA_UNITS::MILLIMETRES;
3378 dim->SetAutoUnits(
true );
3380 dim->SetUnits( units );
3393 dim->SetStart( point );
3395 dim->SetEnd( point );
3415 case T_leader_length:
3431 int orientation =
parseInt(
"orthogonal dimension orientation" );
3437 orientation =
alg::clamp( 0, orientation, 1 );
3446 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3454 NeedSYMBOLorNUMBER();
3455 dim->SetPrefix( FromUTF8() );
3460 NeedSYMBOLorNUMBER();
3461 dim->SetSuffix( FromUTF8() );
3467 int mode =
parseInt(
"dimension units mode" );
3468 mode = std::max( 0, std::min( 4, mode ) );
3474 case T_units_format:
3476 int format =
parseInt(
"dimension units format" );
3488 case T_override_value:
3489 NeedSYMBOLorNUMBER();
3490 dim->SetOverrideTextEnabled(
true );
3491 dim->SetOverrideText( FromUTF8() );
3495 case T_suppress_zeroes:
3496 dim->SetSuppressZeroes(
true );
3500 Expecting(
"prefix, suffix, units, units_format, precision, override_value, "
3501 "suppress_zeroes" );
3510 dim->SetKeepTextAligned(
false );
3512 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3520 dim->SetLineThickness(
parseBoardUnits(
"extension line thickness value" ) );
3524 case T_arrow_length:
3529 case T_text_position_mode:
3531 int mode =
parseInt(
"text position mode" );
3532 mode = std::max( 0, std::min( 3, mode ) );
3538 case T_extension_height:
3541 wxCHECK_MSG( aligned,
nullptr, wxT(
"Invalid extension_height token" ) );
3547 case T_extension_offset:
3548 dim->SetExtensionOffset(
parseBoardUnits(
"extension offset value" ) );
3552 case T_keep_text_aligned:
3553 dim->SetKeepTextAligned(
true );
3559 wxT(
"Invalid text_frame token" ) );
3563 int textFrame =
parseInt(
"text frame mode" );
3571 Expecting(
"thickness, arrow_length, text_position_mode, extension_height, "
3572 "extension_offset" );
3585 if( token != T_pts )
3591 dim->SetStart( point );
3605 if( token != T_pts )
3611 dim->SetEnd( point );
3625 if( token == T_pts )
3647 if( token != T_pts )
3661 if( token != T_pts )
3675 if( token != T_pts )
3689 if( token != T_pts )
3699 Expecting(
"layer, tstamp, gr_text, feature1, feature2, crossbar, arrow1a, "
3700 "arrow1b, arrow2a, or arrow2b" );
3705 dim->SetLocked(
true );
3709 return dim.release();
3731 wxCHECK_MSG( CurTok() == T_module || CurTok() == T_footprint,
nullptr,
3732 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FOOTPRINT." ) );
3740 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
3742 footprint->SetInitialComments( aInitialComments );
3746 if( !IsSymbol( token ) && token != T_NUMBER )
3747 Expecting(
"symbol|number" );
3753 THROW_IO_ERROR( wxString::Format(
_(
"Invalid footprint ID in\nfile: %s\nline: %d\n"
3755 CurSource(), CurLineNumber(), CurOffset() ) );
3758 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3760 if( token == T_LEFT )
3770 int this_version =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
3774 footprint->SetFileFormatVersionAtLoad( this_version );
3786 footprint->SetLocked(
true );
3790 footprint->SetIsPlaced(
true );
3818 footprint->SetPosition( pt );
3821 if( token == T_NUMBER )
3826 else if( token != T_RIGHT )
3828 Expecting( T_RIGHT );
3834 NeedSYMBOLorNUMBER();
3835 footprint->SetLibDescription( FromUTF8() );
3840 NeedSYMBOLorNUMBER();
3841 footprint->SetKeywords( FromUTF8() );
3850 wxString pName = FromUTF8();
3852 wxString pValue = FromUTF8();
3856 if( pName ==
"ki_keywords" || pName ==
"ki_fp_filters" || pName ==
"ki_locked" )
3864 if( pName ==
"ki_description" )
3872 if( pName ==
"Sheetfile" || pName ==
"Sheet file" )
3874 footprint->SetSheetfile( pValue );
3879 if( pName ==
"Sheetname" || pName ==
"Sheet name" )
3881 footprint->SetSheetname( pValue );
3888 if( footprint->HasFieldByName( pName ) )
3890 field = footprint->GetFieldByName( pName );
3895 field = footprint->AddField(
3896 PCB_FIELD( footprint.get(), footprint->GetFieldCount(), pName ) );
3917 NeedSYMBOLorNUMBER();
3918 footprint->SetPath(
KIID_PATH( FromUTF8() ) );
3924 footprint->SetSheetname( FromUTF8() );
3930 footprint->SetSheetfile( FromUTF8() );
3934 case T_autoplace_cost90:
3935 case T_autoplace_cost180:
3936 parseInt(
"legacy auto-place cost" );
3940 case T_private_layers:
3944 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3949 privateLayers.set( it->second );
3951 Expecting(
"layer name" );
3957 privateLayers.set(
Margin,
false );
3960 footprint->SetPrivateLayers( privateLayers );
3964 case T_net_tie_pad_groups:
3965 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3966 footprint->AddNetTiePadGroup( CurStr() );
3970 case T_solder_mask_margin:
3971 footprint->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin "
3976 case T_solder_paste_margin:
3977 footprint->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin "
3982 case T_solder_paste_ratio:
3983 footprint->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin "
3989 footprint->SetLocalClearance(
parseBoardUnits(
"local clearance value" ) );
3993 case T_zone_connect:
3998 case T_thermal_width:
4006 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4014 case T_through_hole:
4026 case T_exclude_from_pos_files:
4030 case T_exclude_from_bom:
4034 case T_allow_missing_courtyard:
4042 case T_allow_soldermask_bridges:
4047 Expecting(
"through_hole, smd, virtual, board_only, exclude_from_pos_files, "
4048 "exclude_from_bom or allow_solder_mask_bridges" );
4062 switch( field->GetId() )
4066 const_cast<KIID&
>( footprint->Reference().m_Uuid ) =
text->m_Uuid;
4072 const_cast<KIID&
>( footprint->Value().m_Uuid ) =
text->m_Uuid;
4078 footprint->Add(
text, ADD_MODE::APPEND,
true );
4086 footprint->Add( textbox, ADD_MODE::APPEND,
true );
4098 footprint->Add( shape, ADD_MODE::APPEND,
true );
4105 footprint->Add(
image, ADD_MODE::APPEND,
true );
4112 footprint->Add( dimension, ADD_MODE::APPEND,
true );
4119 footprint->Add(
pad, ADD_MODE::APPEND,
true );
4126 footprint->Add3DModel( model );
4134 footprint->Add( zone, ADD_MODE::APPEND,
true );
4143 Expecting(
"locked, placed, tedit, tstamp, at, descr, tags, path, "
4144 "autoplace_cost90, autoplace_cost180, solder_mask_margin, "
4145 "solder_paste_margin, solder_paste_ratio, clearance, "
4146 "zone_connect, thermal_gap, attr, fp_text, "
4147 "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, fp_rect, pad, "
4148 "zone, group, generator, version or model" );
4162 if( footprint->GetKeywords().StartsWith( wxT(
"net tie" ) ) )
4166 for(
PAD*
pad : footprint->Pads() )
4168 if( !padGroup.IsEmpty() )
4169 padGroup += wxS(
", " );
4171 padGroup +=
pad->GetNumber();
4174 if( !padGroup.IsEmpty() )
4175 footprint->AddNetTiePadGroup( padGroup );
4179 footprint->SetAttributes( attributes );
4181 footprint->SetFPID( fpid );
4183 return footprint.release();
4189 wxCHECK_MSG( CurTok() == T_pad,
nullptr,
4190 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PAD." ) );
4194 bool foundNet =
false;
4196 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
4199 pad->SetKeepTopBottom(
false );
4201 NeedSYMBOLorNUMBER();
4202 pad->SetNumber( FromUTF8() );
4204 T token = NextTok();
4209 pad->SetAttribute( PAD_ATTRIB::PTH );
4213 pad->SetAttribute( PAD_ATTRIB::SMD );
4221 pad->SetAttribute( PAD_ATTRIB::CONN );
4228 case T_np_thru_hole:
4229 pad->SetAttribute( PAD_ATTRIB::NPTH );
4233 Expecting(
"thru_hole, smd, connect, or np_thru_hole" );
4241 pad->SetShape( PAD_SHAPE::CIRCLE );
4245 pad->SetShape( PAD_SHAPE::RECTANGLE );
4249 pad->SetShape( PAD_SHAPE::OVAL );
4253 pad->SetShape( PAD_SHAPE::TRAPEZOID );
4259 pad->SetShape( PAD_SHAPE::ROUNDRECT );
4263 pad->SetShape( PAD_SHAPE::CUSTOM );
4267 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
4270 std::optional<EDA_ANGLE> thermalBrAngleOverride;
4272 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4274 if( token == T_locked )
4280 if( token != T_LEFT )
4281 Expecting( T_LEFT );
4297 pad->SetFPRelativePosition( pt );
4300 if( token == T_NUMBER )
4305 else if( token != T_RIGHT )
4307 Expecting(
") or angle value" );
4324 bool haveWidth =
false;
4327 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4329 if( token == T_LEFT )
4343 drillSize.
y = drillSize.
x;
4357 pad->SetOffset( pt );
4362 Expecting(
"oval, size, or offset" );
4370 if( (
pad->GetAttribute() != PAD_ATTRIB::SMD )
4371 && (
pad->GetAttribute() != PAD_ATTRIB::CONN ) )
4372 pad->SetDrillSize( drillSize );
4382 pad->SetLayerSet( layerMask );
4391 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d offset: %d" ),
4392 CurSource(), CurLineNumber(), CurOffset() );
4395 NeedSYMBOLorNUMBER();
4400 wxString netName( FromUTF8() );
4410 wxLogError(
_(
"Net name doesn't match ID in\nfile: %s\nline: %d offset: %d" ),
4411 CurSource(), CurLineNumber(), CurOffset() );
4419 NeedSYMBOLorNUMBER();
4420 pad->SetPinFunction( FromUTF8() );
4425 NeedSYMBOLorNUMBER();
4426 pad->SetPinType( FromUTF8() );
4435 case T_solder_mask_margin:
4440 case T_solder_paste_margin:
4445 case T_solder_paste_margin_ratio:
4446 pad->SetLocalSolderPasteMarginRatio(
4447 parseDouble(
"pad local solder paste margin ratio value" ) );
4460 case T_zone_connect:
4465 case T_thermal_width:
4466 case T_thermal_bridge_width:
4471 case T_thermal_bridge_angle:
4482 case T_roundrect_rratio:
4483 pad->SetRoundRectRadiusRatio(
parseDouble(
"roundrect radius ratio" ) );
4487 case T_chamfer_ratio:
4490 if(
pad->GetChamferRectRatio() > 0 )
4491 pad->SetShape( PAD_SHAPE::CHAMFERED_RECT );
4499 bool end_list =
false;
4519 case T_bottom_right:
4524 pad->SetChamferPositions( chamfers );
4529 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
4530 "chamfer_bottom_right" );
4535 pad->SetShape( PAD_SHAPE::CHAMFERED_RECT );
4541 while( token != T_RIGHT )
4547 case T_pad_prop_bga:
pad->SetProperty( PAD_PROP::BGA );
break;
4548 case T_pad_prop_fiducial_glob:
pad->SetProperty( PAD_PROP::FIDUCIAL_GLBL );
break;
4549 case T_pad_prop_fiducial_loc:
pad->SetProperty( PAD_PROP::FIDUCIAL_LOCAL );
break;
4550 case T_pad_prop_testpoint:
pad->SetProperty( PAD_PROP::TESTPOINT );
break;
4551 case T_pad_prop_castellated:
pad->SetProperty( PAD_PROP::CASTELLATED );
break;
4552 case T_pad_prop_heatsink:
pad->SetProperty( PAD_PROP::HEATSINK );
break;
4553 case T_none:
pad->SetProperty( PAD_PROP::NONE );
break;
4554 case T_RIGHT:
break;
4558 Expecting(
"pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc"
4559 " pad_prop_heatsink or pad_prop_castellated" );
4572 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4574 if( token == T_LEFT )
4592 pad->AddPrimitive( numberBox );
4600 pad->AddPrimitive( spokeTemplate );
4605 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
4612 case T_remove_unused_layers:
4613 pad->SetRemoveUnconnected(
true );
4617 case T_keep_end_layers:
4618 pad->SetKeepTopBottom(
true );
4622 case T_zone_layer_connections:
4629 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4633 if( layer < F_Cu || layer >
B_Cu )
4634 Expecting(
"copper layer name" );
4655 Expecting(
"at, locked, drill, layers, net, die_length, roundrect_rratio, "
4656 "solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, "
4657 "clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
4658 "pinfunction, pintype, zone_connect, thermal_width, thermal_gap or "
4666 pad->SetNetCode( 0,
true );
4669 if( thermalBrAngleOverride )
4671 pad->SetThermalSpokeAngle( *thermalBrAngleOverride );
4676 if(
pad->GetShape() == PAD_SHAPE::CIRCLE )
4680 else if(
pad->GetShape() == PAD_SHAPE::CUSTOM
4681 &&
pad->GetAnchorPadShape() == PAD_SHAPE::CIRCLE )
4694 if( !
pad->CanHaveNumber() )
4698 pad->SetNumber( wxEmptyString );
4702 if(
pad->GetSizeX() <= 0 ||
pad->GetSizeY() <= 0 )
4706 wxLogWarning(
_(
"Invalid zero-sized pad pinned to %s in\nfile: %s\nline: %d\noffset: %d" ),
4707 wxT(
"1µm" ), CurSource(), CurLineNumber(), CurOffset() );
4710 return pad.release();
4717 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
4719 if( token != T_LEFT )
4720 Expecting( T_LEFT );
4775 while( (token = NextTok() ) != T_RIGHT )
4788 wxCHECK_RET( CurTok() == T_group,
4789 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
4796 groupInfo.
parent = aParent;
4798 while( ( token = NextTok() ) != T_LEFT )
4800 if( token == T_STRING )
4801 groupInfo.
name = FromUTF8();
4802 else if( token == T_locked )
4805 Expecting(
"group name or locked" );
4820 if( token != T_members )
4821 Expecting( T_members );
4823 while( ( token = NextTok() ) != T_RIGHT )
4828 KIID uuid( CurStr() );
4838 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
4839 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ARC." ) );
4844 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board );
4846 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4848 if( token == T_locked )
4850 arc->SetLocked(
true );
4854 if( token != T_LEFT )
4855 Expecting( T_LEFT );
4864 arc->SetStart( pt );
4890 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d\noffset: %d." ),
4891 CurSource(), CurLineNumber(), CurOffset() );
4907 arc->SetLocked(
true );
4911 Expecting(
"start, mid, end, width, layer, net, tstamp, or status" );
4917 return arc.release();
4923 wxCHECK_MSG( CurTok() == T_segment,
nullptr,
4924 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TRACK." ) );
4929 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
4931 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4933 if( token == T_locked )
4935 track->SetLocked(
true );
4939 if( token != T_LEFT )
4940 Expecting( T_LEFT );
4949 track->SetStart( pt );
4955 track->SetEnd( pt );
4969 wxLogError(
_(
"Invalid net ID in\nfile: '%s'\nline: %d\noffset: %d." ),
4970 CurSource(), CurLineNumber(), CurOffset() );
4986 track->SetLocked(
true );
4990 Expecting(
"start, end, width, layer, net, tstamp, or locked" );
4996 return track.release();
5002 wxCHECK_MSG( CurTok() == T_via,
nullptr,
5003 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_VIA." ) );
5008 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
5011 via->SetRemoveUnconnected(
false );
5012 via->SetKeepStartEnd(
false );
5014 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5016 if( token == T_locked )
5018 via->SetLocked(
true );
5022 if( token == T_LEFT )
5028 via->SetViaType( VIATYPE::BLIND_BURIED );
5032 via->SetViaType( VIATYPE::MICROVIA );
5038 via->SetStart( pt );
5060 via->SetLayerPair( layer1, layer2 );
5068 wxLogError(
_(
"Invalid net ID in\nfile: %s\nline: %d\noffset: %d" ),
5069 CurSource(), CurLineNumber(), CurOffset() );
5075 case T_remove_unused_layers:
5076 via->SetRemoveUnconnected(
true );
5080 case T_keep_end_layers:
5081 via->SetKeepStartEnd(
true );
5085 case T_zone_layer_connections:
5095 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5099 if( layer < F_Cu || layer >
B_Cu )
5100 Expecting(
"copper layer name" );
5125 via->SetLocked(
true );
5135 Expecting(
"blind, micro, at, size, drill, layers, net, free, tstamp, status or "
5140 return via.release();
5146 wxCHECK_MSG( CurTok() == T_zone,
nullptr,
5147 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ZONE." ) );
5155 wxString netnameFromfile;
5158 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
5159 std::map<PCB_LAYER_ID, std::vector<SEG>> legacySegs;
5161 bool addedFilledPolygons =
false;
5162 bool isStrokedFill =
true;
5164 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aParent );
5166 zone->SetAssignedPriority( 0 );
5169 zone->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::ALWAYS );
5171 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5173 if( token == T_locked )
5175 zone->SetLocked(
true );
5179 if( token == T_LEFT )
5193 if( !zone->SetNetCode( tmp,
true ) )
5195 wxLogError(
_(
"Invalid net ID in\nfile: %s;\nline: %d\noffset: %d." ),
5196 CurSource(), CurLineNumber(), CurOffset() );
5203 NeedSYMBOLorNUMBER();
5204 netnameFromfile = FromUTF8();
5226 if( token != T_none && token != T_edge && token != T_full )
5227 Expecting(
"none, edge, or full" );
5232 case T_none: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH;
break;
5233 case T_edge: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE;
break;
5234 case T_full: hatchStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL;
break;
5242 zone->SetAssignedPriority(
parseInt(
"zone priority" ) );
5246 case T_connect_pads:
5247 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5249 if( token == T_LEFT )
5255 zone->SetPadConnection( ZONE_CONNECTION::FULL );
5259 zone->SetPadConnection( ZONE_CONNECTION::NONE );
5262 case T_thru_hole_only:
5263 zone->SetPadConnection( ZONE_CONNECTION::THT_THERMAL );
5272 Expecting(
"yes, no, or clearance" );
5278 case T_min_thickness:
5283 case T_filled_areas_thickness:
5290 isStrokedFill =
false;
5296 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5298 if( token == T_LEFT )
5304 zone->SetIsFilled(
true );
5310 if( token != T_segment && token != T_hatch && token != T_polygon )
5311 Expecting(
"segment, hatch or polygon" );
5316 zone->SetFillMode( ZONE_FILL_MODE::HATCH_PATTERN );
break;
5321 zone->SetFillMode( ZONE_FILL_MODE::POLYGONS );
break;
5327 case T_hatch_thickness:
5337 case T_hatch_orientation:
5340 zone->SetHatchOrientation( orientation );
5345 case T_hatch_smoothing_level:
5346 zone->SetHatchSmoothingLevel(
parseDouble( T_hatch_smoothing_level ) );
5350 case T_hatch_smoothing_value:
5351 zone->SetHatchSmoothingValue(
parseDouble( T_hatch_smoothing_value ) );
5355 case T_hatch_border_algorithm:
5358 if( token != T_hatch_thickness && token != T_min_thickness )
5359 Expecting(
"hatch_thickness or min_thickness" );
5361 zone->SetHatchBorderAlgorithm( token == T_hatch_thickness ? 1 : 0 );
5365 case T_hatch_min_hole_area:
5366 zone->SetHatchHoleMinArea(
parseDouble( T_hatch_min_hole_area ) );
5370 case T_arc_segments:
5380 case T_thermal_bridge_width:
5381 zone->SetThermalReliefSpokeWidth(
parseBoardUnits( T_thermal_bridge_width ) );
5393 if( !zone->GetIsRuleArea() )
5399 if( !zone->GetIsRuleArea() )
5405 Expecting(
"none, chamfer, or fillet" );
5413 if( !zone->GetIsRuleArea() )
5414 zone->SetCornerRadius( tmp );
5418 case T_island_removal_mode:
5419 tmp =
parseInt(
"island_removal_mode" );
5421 if( tmp >= 0 && tmp <= 2 )
5427 case T_island_area_min:
5436 Expecting(
"mode, arc_segments, thermal_gap, thermal_bridge_width, "
5437 "hatch_thickness, hatch_gap, hatch_orientation, "
5438 "hatch_smoothing_level, hatch_smoothing_value, "
5439 "hatch_border_algorithm, hatch_min_hole_area, smoothing, radius, "
5440 "island_removal_mode, or island_area_min" );
5448 zone->SetIsRuleArea(
true );
5451 zone->SetDoNotAllowPads(
false );
5452 zone->SetDoNotAllowFootprints(
false );
5454 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5456 if( token == T_LEFT )
5464 if( token != T_allowed && token != T_not_allowed )
5465 Expecting(
"allowed or not_allowed" );
5466 zone->SetDoNotAllowTracks( token == T_not_allowed );
5472 if( token != T_allowed && token != T_not_allowed )
5473 Expecting(
"allowed or not_allowed" );
5474 zone->SetDoNotAllowVias( token == T_not_allowed );
5480 if( token != T_allowed && token != T_not_allowed )
5481 Expecting(
"allowed or not_allowed" );
5482 zone->SetDoNotAllowCopperPour( token == T_not_allowed );
5488 if( token != T_allowed && token != T_not_allowed )
5489 Expecting(
"allowed or not_allowed" );
5490 zone->SetDoNotAllowPads( token == T_not_allowed );
5496 if( token != T_allowed && token != T_not_allowed )
5497 Expecting(
"allowed or not_allowed" );
5498 zone->SetDoNotAllowFootprints( token == T_not_allowed );
5502 Expecting(
"tracks, vias or copperpour" );
5517 if( token != T_pts )
5520 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5529 zone->AddPolygon( outline );
5533 case T_filled_polygon:
5539 if( token == T_layer )
5545 if( token != T_LEFT )
5546 Expecting( T_LEFT );
5553 filledLayer = zone->GetFirstLayer();
5556 bool island =
false;
5558 if( token == T_island )
5566 if( token != T_pts )
5569 if( !pts.count( filledLayer ) )
5578 zone->SetIsIsland( filledLayer, idx );
5580 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5585 addedFilledPolygons |= !poly.
IsEmpty();
5590 case T_fill_segments:
5594 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5596 if( token != T_LEFT )
5597 Expecting( T_LEFT );
5601 if( token != T_pts )
5605 filledLayer = zone->GetFirstLayer();
5612 legacySegs[filledLayer].push_back( fillSegment );
5622 zone->SetZoneName( FromUTF8() );
5627 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5629 if( token == T_LEFT )
5635 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5637 if( token == T_LEFT )
5645 if( token == T_padvia )
5646 zone->SetTeardropAreaType( TEARDROP_TYPE::TD_VIAPAD );
5647 else if( token == T_track_end )
5648 zone->SetTeardropAreaType( TEARDROP_TYPE::TD_TRACKEND );
5650 Expecting(
"padvia or track_end" );
5656 Expecting(
"type" );
5663 Expecting(
"teardrop" );
5669 Expecting(
"net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
5670 "fill, polygon, filled_polygon, fill_segments, attr, or name" );
5674 if( zone->GetNumCorners() > 2 )
5676 if( !zone->IsOnCopperLayer() )
5683 zone->SetBorderDisplayStyle( hatchStyle, hatchPitch,
true );
5686 if( addedFilledPolygons )
5688 if( isStrokedFill && !zone->GetIsRuleArea() )
5693 _(
"Legacy zone fill strategy is not supported anymore.\nZone fills will "
5694 "be converted on best-effort basis." ) );
5699 if( zone->GetMinThickness() > 0 )
5701 for(
auto& [layer, polyset] : pts )
5703 polyset.InflateWithLinkedHoles(
5710 for(
auto& [layer, polyset] : pts )
5711 zone->SetFilledPolysList( layer, polyset );
5713 zone->CalculateFilledArea();
5715 else if( legacySegs.size() > 0 )
5723 wxLogWarning(
_(
"The legacy segment zone fill mode is no longer supported.\n"
5724 "Zone fills will be converted on a best-effort basis." ) );
5730 for(
const auto& [layer, segments] : legacySegs )
5734 if( zone->HasFilledPolysForLayer( layer ) )
5737 for(
const auto& seg : segments )
5748 zone->SetFilledPolysList( layer, layerFill );
5749 zone->CalculateFilledArea();
5757 bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsRuleArea();
5763 if( zone_has_net && ( zone->GetNet()->GetNetname() != netnameFromfile ) )
5792 zone->SetNeedRefill(
false );
5794 return zone.release();
5800 wxCHECK_MSG( CurTok() == T_target,
nullptr,
5801 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TARGET." ) );
5806 std::unique_ptr<PCB_TARGET> target = std::make_unique<PCB_TARGET>(
nullptr );
5808 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5810 if( token == T_LEFT )
5816 target->SetShape( 1 );
5820 target->SetShape( 0 );
5826 target->SetPosition( pt );
5852 Expecting(
"x, plus, at, size, width, layer or tstamp" );
5856 return target.release();
5871 aId =
KIID( CurStr() );
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
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
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.
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.
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.
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.
FOOTPRINTS & Footprints()
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.
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)
unsigned GetNetCount() const
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
bool m_LegacyCopperEdgeClearanceLoaded
void SetFileFormatVersionAtLoad(int aVersion)
KICAD_T Type() const
Returns the type of object.
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
void SetTextSize(VECTOR2I aNewSize)
const EDA_ANGLE & GetTextAngle() const
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)
virtual void SetVisible(bool aVisible)
void SetLineSpacing(double aLineSpacing)
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
void SetKeepUpright(bool aKeepUpright)
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetItalic(bool aItalic)
void SetFont(KIFONT::FONT *aFont)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
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()
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=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.
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
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 const wxChar * 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...
void SetCustomShapeInZoneOpt(CUST_PAD_SHAPE_IN_ZONE aOption)
Set the option for the custom pad shape to use as clearance area in copper zones.
void SetAnchorPadShape(PAD_SHAPE aShape)
Set the shape of the anchor pad for custom shaped pads.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetWidthMils(int aWidthInMils)
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
static const wxChar Custom[]
"User" defined page type
void SetHeightMils(int aHeightInMils)
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.
Object to handle a bitmap image that can be inserted in a PCB.
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)
A set of BOARD_ITEMs (i.e., without duplicates).
bool parsePAD_option(PAD *aPad)
PCB_TRACK * parsePCB_TRACK()
PCB_LAYER_ID parseBoardItemLayer()
Parse the layer definition of a BOARD_ITEM object.
void parseRenderCache(EDA_TEXT *text)
Parse the render cache for any object derived from EDA_TEXT.
LSET_MAP m_layerMasks
map layer names to their masks
void init()
Clear and re-establish m_layerMap with the default layer names.
PAD * parsePAD(FOOTPRINT *aParent=nullptr)
ZONE * parseZONE(BOARD_ITEM_CONTAINER *aParent)
FOOTPRINT * parseFOOTPRINT_unchecked(wxArrayString *aInitialComments=nullptr)
void parseEDA_TEXT(EDA_TEXT *aText)
Parse the common settings for any object derived from EDA_TEXT.
int m_requiredVersion
set to the KiCad format version this board requires
int parseBoardUnits()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
TIME_PT m_lastProgressTime
for progress reporting
std::pair< wxString, wxString > parseBoardProperty()
void parseTEARDROP_PARAMETERS(TEARDROP_PARAMETERS *tdParams)
std::vector< GROUP_INFO > m_groupInfos
BOARD * parseBOARD_unchecked()
int getNetCode(int aNetCode)
< Convert net code using the mapping table if available, otherwise returns unchanged net code if < 0 ...
bool m_appendToExisting
reading into an existing board; reset UUIDs
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
void parseDefaults(BOARD_DESIGN_SETTINGS &aSettings)
void parseOutlinePoints(SHAPE_LINE_CHAIN &aPoly)
Parses possible outline points and stores them into aPoly.
bool m_tooRecent
true if version parses as later than supported
bool m_showLegacySegmentZoneWarning
PCB_TARGET * parsePCB_TARGET()
FP_3DMODEL * parse3DModel()
void parseGROUP(BOARD_ITEM *aParent)
LSET parseBoardItemLayersAsMask()
Parse the layers definition of a BOARD_ITEM object.
VECTOR2I parseXY()
Parse a coordinate pair (xy X Y) in board units (mm).
PCB_DIMENSION_BASE * parseDIMENSION(BOARD_ITEM *aParent)
std::function< bool(wxString aTitle, int aIcon, wxString aMsg, wxString aAction)> m_queryUserCallback
std::chrono::time_point< CLOCK > TIME_PT
PCB_BITMAP * parsePCB_BITMAP(BOARD_ITEM *aParent)
wxString GetRequiredVersion()
Return a string representing the version of KiCad required to open this file.
void parsePCB_TEXT_effects(PCB_TEXT *aText)
bool m_showLegacy5ZoneWarning
PCB_SHAPE * parsePCB_SHAPE(BOARD_ITEM *aParent)
FOOTPRINT * parseFOOTPRINT(wxArrayString *aInitialComments=nullptr)
PCB_TEXT * parsePCB_TEXT(BOARD_ITEM *aParent)
PCB_TEXTBOX * parsePCB_TEXTBOX(BOARD_ITEM *aParent)
void resolveGroups(BOARD_ITEM *aParent)
Called after parsing a footprint definition or board to build the group membership lists.
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
T lookUpLayer(const M &aMap)
Parse the current token for the layer definition of a BOARD_ITEM object.
std::vector< int > m_netCodes
net codes mapping for boards being loaded
void parseGeneralSection()
void createOldLayerMapping(std::unordered_map< std::string, std::string > &aMap)
Create a mapping from the (short-lived) bug where layer names were translated.
void parseDefaultTextDims(BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
void parseLayer(LAYER *aLayer)
unsigned m_lineCount
for progress reporting
void skipCurrent()
Skip the current token level, i.e search for the RIGHT parenthesis which closes the current descripti...
LAYER_ID_MAP m_layerIndices
map layer name to it's index
bool IsValidBoardHeader()
Partially parse the input and check if it matches expected header.
void pushValueIntoMap(int aIndex, int aValue)
Add aValue value in netcode mapping (m_netCodes) at aIndex.
The parser for PCB_PLOT_PARAMS.
Parameters and options when plotting/printing a board.
void Parse(PCB_PLOT_PARAMS_PARSER *aParser)
void SetIsProxyItem(bool aIsProxy=true) override