58 using namespace PCB_KEYS_T;
63 m_showLegacyZoneWarning =
true;
65 m_requiredVersion = 0;
66 m_layerIndices.clear();
68 m_resetKIIDMap.clear();
97 for(
int i=1; i<=14; ++i )
99 std::string key =
StrPrintf(
"Inner%d.Cu", i );
111 while( ( token = NextTok() ) != T_EOF )
113 if( token == T_LEFT )
116 if( token == T_RIGHT )
132 if( (
int)m_netCodes.size() <= aIndex )
133 m_netCodes.resize( static_cast<std::size_t>( aIndex ) + 1 );
135 m_netCodes[aIndex] = aValue;
145 double fval = strtod( CurText(), &tmp );
150 error.Printf(
_(
"Invalid floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
151 CurSource(), CurLineNumber(), CurOffset() );
156 if( CurText() == tmp )
159 error.Printf(
_(
"Missing floating point number in\nfile: \"%s\"\nline: %d\noffset: %d" ),
160 CurSource(), CurLineNumber(), CurOffset() );
175 else if( token == T_no )
178 Expecting(
"yes or no" );
186 int year, month, day;
188 year = m_requiredVersion / 10000;
189 month = ( m_requiredVersion / 100 ) - ( year * 100 );
190 day = m_requiredVersion - ( year * 10000 ) - ( month * 100 );
195 if( day <= 0 || month <= 0 || month > 12 ||
196 day > wxDateTime::GetNumberOfDays( (wxDateTime::Month)( month - 1 ), year ) )
199 err.Printf(
_(
"Cannot interpret date code %d" ), m_requiredVersion );
203 wxDateTime date( day, (wxDateTime::Month)( month - 1 ), year, 0, 0, 0, 0 );
204 return date.FormatDate();
210 if( CurTok() != T_LEFT )
219 pt.x = parseBoardUnits(
"X coordinate" );
220 pt.y = parseBoardUnits(
"Y coordinate" );
230 wxPoint pt = parseXY();
251 return { pName, pValue };
257 wxCHECK_RET( CurTok() == T_effects,
258 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as EDA_TEXT." ) );
264 bool foundTextSize =
false;
266 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
268 if( token == T_LEFT )
274 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
276 if( token == T_LEFT )
284 sz.SetHeight( parseBoardUnits(
"text height" ) );
285 sz.SetWidth( parseBoardUnits(
"text width" ) );
289 foundTextSize =
true;
307 Expecting(
"size, bold, or italic" );
313 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
315 if( token == T_LEFT )
341 Expecting(
"left, right, top, bottom, or mirror" );
352 Expecting(
"font, justify, or hide" );
360 const double defaultTextSize = 1.524 *
IU_PER_MM;
362 aText->
SetTextSize( wxSize( defaultTextSize, defaultTextSize ) );
369 wxCHECK_MSG( CurTok() == T_model,
NULL,
370 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FP_3DMODEL." ) );
375 NeedSYMBOLorNUMBER();
378 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
380 if( token == T_LEFT )
464 Expecting(
"at, hide, opacity, offset, scale, or rotate" );
479 m_groupInfos.clear();
484 std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
488 if( token != T_LEFT )
494 if( m_board ==
NULL )
495 m_board =
new BOARD();
502 item = (
BOARD_ITEM*) parseFOOTPRINT( initial_comments.release() );
507 err.Printf(
_(
"Unknown token \"%s\"" ), FromUTF8() );
511 resolveGroups( item );
521 return parseBOARD_unchecked();
536 std::map<wxString, wxString> properties;
540 std::vector<BOARD_ITEM*> bulkAddedItems;
543 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
545 if( token != T_LEFT )
550 if( token == T_page && m_requiredVersion <= 20200119 )
556 parseGeneralSection();
576 properties.insert( parseProperty() );
585 m_board->m_LegacyNetclassesLoaded =
true;
594 item = parsePCB_SHAPE();
596 bulkAddedItems.push_back( item );
600 item = parsePCB_TEXT();
602 bulkAddedItems.push_back( item );
606 item = parseDIMENSION();
608 bulkAddedItems.push_back( item );
613 item = parseFOOTPRINT();
615 bulkAddedItems.push_back( item );
621 bulkAddedItems.push_back( item );
627 bulkAddedItems.push_back( item );
631 parseGROUP( m_board );
637 bulkAddedItems.push_back( item );
641 item = parseZONE( m_board );
643 bulkAddedItems.push_back( item );
647 item = parsePCB_TARGET();
649 bulkAddedItems.push_back( item );
654 err.Printf(
_(
"Unknown token \"%s\"" ), FromUTF8() );
659 if( bulkAddedItems.size() > 0 )
660 m_board->FinalizeBulkAdd( bulkAddedItems );
662 m_board->SetProperties( properties );
664 if( m_undefinedLayers.size() > 0 )
667 std::vector<BOARD_ITEM*> deleteList;
668 wxString msg =
wxString::Format(
_(
"Items found on undefined layers. Do you wish to\n" 669 "rescue them to the User.Comments layer?" ) );
672 for(
const wxString& undefinedLayer : m_undefinedLayers )
673 details += wxT(
"\n " ) + undefinedLayer;
675 wxRichMessageDialog dlg(
nullptr, msg,
_(
"Warning" ),
676 wxYES_NO | wxCANCEL | wxCENTRE | wxICON_WARNING | wxSTAY_ON_TOP );
677 dlg.ShowDetailedText( details );
678 dlg.SetYesNoCancelLabels(
_(
"Rescue" ),
_(
"Delete" ),
_(
"Cancel" ) );
680 switch( dlg.ShowModal() )
682 case wxID_YES: deleteItems =
false;
break;
683 case wxID_NO: deleteItems =
true;
break;
690 if( curr_item->GetLayer() ==
Rescue )
693 deleteList.push_back( curr_item );
699 for(
auto segm : m_board->Tracks() )
709 via->
LayerPair( &top_layer, &bottom_layer );
714 deleteList.push_back( via );
720 if( bottom_layer ==
Rescue )
734 for(
BOARD_ITEM* drawing : m_board->Drawings() )
735 visitItem( drawing );
737 for(
FOOTPRINT* fp : m_board->Footprints() )
739 for(
BOARD_ITEM* drawing : fp->GraphicalItems() )
740 visitItem( drawing );
747 m_board->Delete( curr_item );
749 m_undefinedLayers.clear();
758 auto getItem = [&](
const KIID& aId )
762 if( dynamic_cast<BOARD*>( aParent ) )
764 aItem = static_cast<BOARD*>( aParent )->GetItem( aId );
768 static_cast<FOOTPRINT*>( aParent )->RunOnChildren(
771 if( child->
m_Uuid == aId )
784 for(
size_t idx = 0; idx < m_groupInfos.size(); idx++ )
790 const_cast<KIID&>( group->
m_Uuid ) = aGrp.
uuid;
793 static_cast<FOOTPRINT*>( aGrp.
parent )->Add( group );
795 static_cast<BOARD*>( aGrp.
parent )->Add( group );
800 for(
size_t idx = 0; idx < m_groupInfos.size(); idx++ )
808 PCB_GROUP* group = static_cast<PCB_GROUP*>( bItem );
815 item = getItem( m_resetKIIDMap[ aUuid.
AsString() ] );
817 item = getItem( aUuid );
819 if( item && item->Type() !=
NOT_USED )
821 switch( item->Type() )
827 if( item->GetParent() == group->
GetParent() )
845 m_board->GroupsSanityCheck(
true );
851 wxCHECK_RET( CurTok() == T_kicad_pcb,
852 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
858 if( tok == T_version )
860 m_requiredVersion =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
876 m_requiredVersion = 20201115;
886 m_board->SetFileFormatVersionAtLoad( m_requiredVersion );
892 wxCHECK_RET( CurTok() == T_general,
893 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) +
894 wxT(
" as a general section." ) );
898 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
900 if( token != T_LEFT )
908 m_board->GetDesignSettings().SetBoardThickness( parseBoardUnits( T_thickness ) );
913 while( ( token = NextTok() ) != T_RIGHT )
915 if( !IsSymbol( token ) && token != T_NUMBER )
916 Expecting(
"symbol or number" );
925 wxCHECK_RET( ( CurTok() == T_page && m_requiredVersion <= 20200119 ) || CurTok() == T_paper,
926 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
933 wxString pageType = FromUTF8();
935 if( !pageInfo.
SetType( pageType ) )
938 err.Printf(
_(
"Page type \"%s\" is not valid " ), FromUTF8() );
949 else if( width > 1200.0 )
956 else if( height > 1200.0 )
965 if( token == T_portrait )
970 else if( token != T_RIGHT )
972 Expecting(
"portrait|)" );
975 m_board->SetPageSettings( pageInfo );
981 wxCHECK_RET( CurTok() == T_title_block,
982 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) +
983 wxT(
" as TITLE_BLOCK." ) );
988 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
990 if( token != T_LEFT )
1004 titleBlock.
SetDate( FromUTF8() );
1019 int commentNumber =
parseInt(
"comment" );
1021 switch( commentNumber )
1070 err.Printf( wxT(
"%d is not a valid title block comment number" ), commentNumber );
1077 Expecting(
"title, date, rev, company, or comment" );
1083 m_board->SetTitleBlock( titleBlock );
1092 std::string userName;
1094 bool isVisible =
true;
1098 if( CurTok() != T_LEFT )
1099 Expecting( T_LEFT );
1104 NeedSYMBOLorNUMBER();
1113 if( token == T_hide )
1118 else if( token == T_STRING )
1120 userName = CurText();
1123 else if( token != T_RIGHT )
1125 Expecting(
"hide, user defined name, or )" );
1133 if( !userName.empty() )
1148 int dielectric_idx = 1;
1149 BOARD_STACKUP& stackup = m_board->GetDesignSettings().GetStackupDescriptor();
1151 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1153 if( CurTok() != T_LEFT )
1154 Expecting( T_LEFT );
1158 if( token != T_layer )
1162 case T_copper_finish:
1168 case T_edge_plating:
1174 case T_dielectric_constraints:
1180 case T_edge_connector:
1184 if( token == T_yes )
1186 else if( token == T_bevelled )
1192 case T_castellated_pads:
1226 else if( layerId >=
F_Cu && layerId <=
B_Cu )
1239 stackup.
Add( item );
1242 Expecting(
"layer_name" );
1244 bool has_next_sublayer =
true;
1245 int sublayer_idx = 0;
1248 while( has_next_sublayer )
1250 has_next_sublayer =
false;
1252 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1254 if( token == T_addsublayer )
1256 has_next_sublayer =
true;
1260 if( token == T_LEFT )
1273 item->
SetThickness( parseBoardUnits( T_thickness ), sublayer_idx );
1276 if( token == T_LEFT )
1279 if( token == T_locked )
1301 case T_loss_tangent:
1322 if( has_next_sublayer )
1330 if( token != T_RIGHT )
1336 m_board->GetDesignSettings().m_HasStackup =
true;
1347 aMap[
"Adesivo.Retro"] =
"B.Adhes";
1348 aMap[
"Adesivo.Fronte"] =
"F.Adhes";
1349 aMap[
"Pasta.Retro"] =
"B.Paste";
1350 aMap[
"Pasta.Fronte"] =
"F.Paste";
1351 aMap[
"Serigrafia.Retro"] =
"B.SilkS";
1352 aMap[
"Serigrafia.Fronte"] =
"F.SilkS";
1353 aMap[
"Maschera.Retro"] =
"B.Mask";
1354 aMap[
"Maschera.Fronte"] =
"F.Mask";
1355 aMap[
"Grafica"] =
"Dwgs.User";
1356 aMap[
"Commenti"] =
"Cmts.User";
1357 aMap[
"Eco1"] =
"Eco1.User";
1358 aMap[
"Eco2"] =
"Eco2.User";
1359 aMap[
"Contorno.scheda"] =
"Edge.Cuts";
1362 aMap[
"Kleju_Dolna"] =
"B.Adhes";
1363 aMap[
"Kleju_Gorna"] =
"F.Adhes";
1364 aMap[
"Pasty_Dolna"] =
"B.Paste";
1365 aMap[
"Pasty_Gorna"] =
"F.Paste";
1366 aMap[
"Opisowa_Dolna"] =
"B.SilkS";
1367 aMap[
"Opisowa_Gorna"] =
"F.SilkS";
1368 aMap[
"Maski_Dolna"] =
"B.Mask";
1369 aMap[
"Maski_Gorna"] =
"F.Mask";
1370 aMap[
"Rysunkowa"] =
"Dwgs.User";
1371 aMap[
"Komentarzy"] =
"Cmts.User";
1372 aMap[
"ECO1"] =
"Eco1.User";
1373 aMap[
"ECO2"] =
"Eco2.User";
1374 aMap[
"Krawedziowa"] =
"Edge.Cuts";
1377 aMap[
"Dessous.Adhes"] =
"B.Adhes";
1378 aMap[
"Dessus.Adhes"] =
"F.Adhes";
1379 aMap[
"Dessous.Pate"] =
"B.Paste";
1380 aMap[
"Dessus.Pate"] =
"F.Paste";
1381 aMap[
"Dessous.SilkS"] =
"B.SilkS";
1382 aMap[
"Dessus.SilkS"] =
"F.SilkS";
1383 aMap[
"Dessous.Masque"] =
"B.Mask";
1384 aMap[
"Dessus.Masque"] =
"F.Mask";
1385 aMap[
"Dessin.User"] =
"Dwgs.User";
1386 aMap[
"Contours.Ci"] =
"Edge.Cuts";
1392 wxCHECK_RET( CurTok() == T_layers,
1393 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layers." ) );
1398 int copperLayerCount = 0;
1400 bool anyHidden =
false;
1402 std::unordered_map< std::string, std::string > v3_layer_names;
1403 std::vector<LAYER> cu;
1405 createOldLayerMapping( v3_layer_names );
1407 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1409 parseLayer( &layer );
1414 cu.push_back( layer );
1427 cu[cu.size()-1].m_number =
B_Cu;
1429 for(
unsigned i=0; i < cu.size()-1; ++i )
1434 for( std::vector<LAYER>::const_iterator it = cu.begin(); it<cu.end(); ++it )
1436 enabledLayers.set( it->m_number );
1439 visibleLayers.set( it->m_number );
1443 m_board->SetLayerDescr(
PCB_LAYER_ID( it->m_number ), *it );
1451 copperLayerCount = cu.size();
1455 while( token != T_RIGHT )
1457 LAYER_ID_MAP::const_iterator it = m_layerIndices.find(
UTF8( layer.
m_name ) );
1459 if( it == m_layerIndices.end() )
1461 auto new_layer_it = v3_layer_names.find( layer.
m_name.ToStdString() );
1463 if( new_layer_it != v3_layer_names.end() )
1464 it = m_layerIndices.find( new_layer_it->second );
1466 if( it == m_layerIndices.end() )
1469 _(
"Layer \"%s\" in file \"%s\" at line %d, is not in fixed layer hash" ),
1481 m_layerIndices[
UTF8( layer.
m_name ) ] = it->second;
1482 m_layerMasks[
UTF8( layer.
m_name ) ] = it->second;
1483 layer.
m_name = it->first;
1487 enabledLayers.set( layer.
m_number );
1490 visibleLayers.set( layer.
m_number );
1494 m_board->SetLayerDescr( it->second, layer );
1498 if( token != T_LEFT )
1501 parseLayer( &layer );
1505 if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
1508 _(
"%d is not a valid layer count" ), copperLayerCount );
1513 m_board->SetCopperLayerCount( copperLayerCount );
1514 m_board->SetEnabledLayers( enabledLayers );
1519 m_board->m_LegacyVisibleLayers = visibleLayers;
1523 template<
class T,
class M>
1527 typename M::const_iterator it = aMap.find( curText );
1529 if( it == aMap.end() )
1531 m_undefinedLayers.insert( curText );
1536 if( it->second ==
Rescue )
1537 m_undefinedLayers.insert( curText );
1546 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layer." ) );
1550 PCB_LAYER_ID layerIndex = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
1560 wxCHECK_MSG( CurTok() == T_layers,
LSET(),
1561 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) +
1562 wxT(
" as item layer mask." ) );
1566 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
1568 LSET mask = lookUpLayer<LSET>( m_layerMasks );
1578 wxCHECK_RET( CurTok() == T_setup,
1579 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as setup." ) );
1582 NETCLASS* defaultNetClass = m_board->GetDesignSettings().GetDefault();
1590 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1592 if( token != T_LEFT )
1593 Expecting( T_LEFT );
1600 parseBoardStackup();
1603 case T_last_trace_width:
1604 parseBoardUnits( T_last_trace_width );
1608 case T_user_trace_width:
1614 designSettings.
m_TrackWidthList.push_back( parseBoardUnits( T_user_trace_width ) );
1615 m_board->m_LegacyDesignSettingsLoaded =
true;
1620 case T_trace_clearance:
1621 defaultNetClass->
SetClearance( parseBoardUnits( T_trace_clearance ) );
1622 m_board->m_LegacyDesignSettingsLoaded =
true;
1626 case T_zone_clearance:
1628 m_board->m_LegacyDesignSettingsLoaded =
true;
1632 case T_zone_45_only:
1634 m_board->m_LegacyDesignSettingsLoaded =
true;
1638 case T_clearance_min:
1639 designSettings.
m_MinClearance = parseBoardUnits( T_clearance_min );
1640 m_board->m_LegacyDesignSettingsLoaded =
true;
1646 m_board->m_LegacyDesignSettingsLoaded =
true;
1651 defaultNetClass->
SetViaDiameter( parseBoardUnits( T_via_size ) );
1652 m_board->m_LegacyDesignSettingsLoaded =
true;
1657 defaultNetClass->
SetViaDrill( parseBoardUnits( T_via_drill ) );
1658 m_board->m_LegacyDesignSettingsLoaded =
true;
1662 case T_via_min_annulus:
1664 m_board->m_LegacyDesignSettingsLoaded =
true;
1668 case T_via_min_size:
1669 designSettings.
m_ViasMinSize = parseBoardUnits( T_via_min_size );
1670 m_board->m_LegacyDesignSettingsLoaded =
true;
1674 case T_through_hole_min:
1676 m_board->m_LegacyDesignSettingsLoaded =
true;
1681 case T_via_min_drill:
1683 m_board->m_LegacyDesignSettingsLoaded =
true;
1687 case T_hole_to_hole_min:
1688 designSettings.
m_HoleToHoleMin = parseBoardUnits( T_hole_to_hole_min );
1689 m_board->m_LegacyDesignSettingsLoaded =
true;
1695 int viaSize = parseBoardUnits(
"user via size" );
1696 int viaDrill = parseBoardUnits(
"user via drill" );
1703 m_board->m_LegacyDesignSettingsLoaded =
true;
1710 m_board->m_LegacyDesignSettingsLoaded =
true;
1715 defaultNetClass->
SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
1716 m_board->m_LegacyDesignSettingsLoaded =
true;
1720 case T_uvias_allowed:
1722 m_board->m_LegacyDesignSettingsLoaded =
true;
1726 case T_blind_buried_vias_allowed:
1728 m_board->m_LegacyDesignSettingsLoaded =
true;
1732 case T_uvia_min_size:
1734 m_board->m_LegacyDesignSettingsLoaded =
true;
1738 case T_uvia_min_drill:
1740 m_board->m_LegacyDesignSettingsLoaded =
true;
1744 case T_user_diff_pair:
1746 int width = parseBoardUnits(
"user diff-pair width" );
1747 int gap = parseBoardUnits(
"user diff-pair gap" );
1748 int viaGap = parseBoardUnits(
"user diff-pair via gap" );
1750 m_board->m_LegacyDesignSettingsLoaded =
true;
1755 case T_segment_width:
1757 m_board->m_LegacyDesignSettingsLoaded =
true;
1763 m_board->m_LegacyDesignSettingsLoaded =
true;
1767 case T_mod_edge_width:
1769 m_board->m_LegacyDesignSettingsLoaded =
true;
1773 case T_pcb_text_width:
1775 m_board->m_LegacyDesignSettingsLoaded =
true;
1779 case T_mod_text_width:
1781 m_board->m_LegacyDesignSettingsLoaded =
true;
1785 case T_pcb_text_size:
1788 m_board->m_LegacyDesignSettingsLoaded =
true;
1792 case T_mod_text_size:
1795 m_board->m_LegacyDesignSettingsLoaded =
true;
1800 parseDefaults( designSettings );
1801 m_board->m_LegacyDesignSettingsLoaded =
true;
1807 sz.SetWidth( parseBoardUnits(
"master pad width" ) );
1808 sz.SetHeight( parseBoardUnits(
"master pad height" ) );
1810 m_board->m_LegacyDesignSettingsLoaded =
true;
1817 int drillSize = parseBoardUnits( T_pad_drill );
1819 m_board->m_LegacyDesignSettingsLoaded =
true;
1824 case T_pad_to_mask_clearance:
1829 case T_solder_mask_min_width:
1834 case T_pad_to_paste_clearance:
1839 case T_pad_to_paste_clearance_ratio:
1844 case T_aux_axis_origin:
1846 int x = parseBoardUnits(
"auxiliary origin X" );
1847 int y = parseBoardUnits(
"auxiliary origin Y" );
1857 int x = parseBoardUnits(
"grid origin X" );
1858 int y = parseBoardUnits(
"grid origin Y" );
1867 case T_visible_elements:
1874 for(
size_t i = 0; i <
sizeof( int ) * CHAR_BIT; i++ )
1875 m_board->m_LegacyVisibleItems.set( i, visible & ( 1u << i ) );
1882 designSettings.
m_MaxError = parseBoardUnits( T_max_error );
1883 m_board->m_LegacyDesignSettingsLoaded =
true;
1887 case T_filled_areas_thickness:
1889 m_board->m_LegacyDesignSettingsLoaded =
true;
1893 case T_pcbplotparams:
1899 parser.SyncLineReaderWith( *
this );
1901 plotParams.
Parse( &parser );
1902 SyncLineReaderWith( parser );
1904 m_board->SetPlotOptions( plotParams );
1909 Unexpected( CurText() );
1919 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1921 if( token != T_LEFT )
1922 Expecting( T_LEFT );
1928 case T_edge_clearance:
1930 m_board->m_LegacyCopperEdgeClearanceLoaded =
true;
1934 case T_copper_line_width:
1939 case T_copper_text_dims:
1943 case T_courtyard_line_width:
1948 case T_edge_cuts_line_width:
1953 case T_silk_line_width:
1958 case T_silk_text_dims:
1962 case T_fab_layers_line_width:
1967 case T_fab_layers_text_dims:
1971 case T_other_layers_line_width:
1976 case T_other_layers_text_dims:
1980 case T_dimension_units:
1982 static_cast<DIM_UNITS_MODE>(
parseInt(
"dimension units" ) );
1986 case T_dimension_precision:
1992 Unexpected( CurText() );
2002 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2004 if( token == T_LEFT )
2010 aSettings.
m_TextSize[ aLayer ].x = parseBoardUnits(
"default text size X" );
2011 aSettings.
m_TextSize[ aLayer ].y = parseBoardUnits(
"default text size Y" );
2016 aSettings.
m_TextThickness[ aLayer ] = parseBoardUnits(
"default text width" );
2024 case T_keep_upright:
2029 Expecting(
"size, thickness, italic or keep_upright" );
2037 wxCHECK_RET( CurTok() == T_net,
2038 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net." ) );
2040 int netCode =
parseInt(
"net number" );
2042 NeedSYMBOLorNUMBER();
2043 wxString
name = FromUTF8();
2053 m_board->Add( net );
2056 pushValueIntoMap( netCode, net->
GetNetCode() );
2063 wxCHECK_RET( CurTok() == T_net_class,
2064 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net class." ) );
2068 NETCLASSPTR nc = std::make_shared<NETCLASS>( wxEmptyString );
2071 NeedSYMBOLorNUMBER();
2072 nc->SetName( FromUTF8() );
2074 nc->SetDescription( FromUTF8() );
2076 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2078 if( token != T_LEFT )
2079 Expecting( T_LEFT );
2086 nc->SetClearance( parseBoardUnits( T_clearance ) );
2090 nc->SetTrackWidth( parseBoardUnits( T_trace_width ) );
2094 nc->SetViaDiameter( parseBoardUnits( T_via_dia ) );
2098 nc->SetViaDrill( parseBoardUnits( T_via_drill ) );
2102 nc->SetuViaDiameter( parseBoardUnits( T_uvia_dia ) );
2106 nc->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
2109 case T_diff_pair_width:
2110 nc->SetDiffPairWidth( parseBoardUnits( T_diff_pair_width ) );
2113 case T_diff_pair_gap:
2114 nc->SetDiffPairGap( parseBoardUnits( T_diff_pair_gap ) );
2118 NeedSYMBOLorNUMBER();
2119 nc->Add( FromUTF8() );
2123 Expecting(
"clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, " 2124 "diff_pair_width, diff_pair_gap or add_net" );
2130 if( !m_board->GetDesignSettings().GetNetClasses().Add( nc ) )
2138 error.Printf(
_(
"Duplicate NETCLASS name \"%s\" in file \"%s\" at line %d, offset %d" ),
2139 nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(), CurOffset() );
2147 wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
2148 CurTok() == T_gr_rect || CurTok() == T_gr_line || CurTok() == T_gr_poly,
NULL,
2149 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_SHAPE." ) );
2153 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
nullptr );
2158 shape->SetShape(
S_ARC );
2164 if( token != T_start && token != T_center )
2165 Expecting( T_start );
2167 pt.x = parseBoardUnits(
"X coordinate" );
2168 pt.y = parseBoardUnits(
"Y coordinate" );
2169 shape->SetCenter( pt );
2174 if( token != T_end )
2177 pt.x = parseBoardUnits(
"X coordinate" );
2178 pt.y = parseBoardUnits(
"Y coordinate" );
2179 shape->SetArcStart( pt );
2188 if( token != T_center )
2189 Expecting( T_center );
2191 pt.x = parseBoardUnits(
"X coordinate" );
2192 pt.y = parseBoardUnits(
"Y coordinate" );
2193 shape->SetCenter( pt );
2199 if( token != T_end )
2202 pt.x = parseBoardUnits(
"X coordinate" );
2203 pt.y = parseBoardUnits(
"Y coordinate" );
2204 shape->SetEnd( pt );
2213 if( token != T_pts )
2216 shape->SetStart( parseXY() );
2217 shape->SetBezControl1( parseXY() );
2218 shape->SetBezControl2( parseXY() );
2219 shape->SetEnd( parseXY() );
2224 shape->SetShape(
S_RECT );
2228 if( token != T_start )
2229 Expecting( T_start );
2231 pt.x = parseBoardUnits(
"X coordinate" );
2232 pt.y = parseBoardUnits(
"Y coordinate" );
2233 shape->SetStart( pt );
2238 if( token != T_end )
2241 pt.x = parseBoardUnits(
"X coordinate" );
2242 pt.y = parseBoardUnits(
"Y coordinate" );
2243 shape->SetEnd( pt );
2252 if( token != T_start )
2253 Expecting( T_start );
2255 pt.x = parseBoardUnits(
"X coordinate" );
2256 pt.y = parseBoardUnits(
"Y coordinate" );
2257 shape->SetStart( pt );
2262 if( token != T_end )
2265 pt.x = parseBoardUnits(
"X coordinate" );
2266 pt.y = parseBoardUnits(
"Y coordinate" );
2267 shape->SetEnd( pt );
2274 shape->SetWidth( 0 );
2278 if( token != T_pts )
2281 std::vector< wxPoint > pts;
2283 while( (token = NextTok() ) != T_RIGHT )
2284 pts.push_back( parseXY() );
2286 shape->SetPolyPoints( pts );
2291 Expecting(
"gr_arc, gr_circle, gr_curve, gr_line, gr_poly, or gp_rect" );
2294 bool foundFill =
false;
2296 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2298 if( token != T_LEFT )
2299 Expecting( T_LEFT );
2306 shape->SetAngle(
parseDouble(
"segment angle" ) * 10.0 );
2311 shape->SetLayer( parseBoardItemLayer() );
2316 shape->SetWidth( parseBoardUnits( T_width ) );
2322 const_cast<KIID&>( shape->m_Uuid ) = CurStrToKIID();
2329 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2331 if( token == T_LEFT )
2340 shape->SetFilled(
true );
2344 shape->SetFilled(
false );
2348 Expecting(
"yes, none, solid" );
2355 shape->SetStatus( static_cast<STATUS_FLAGS>(
parseHex() ) );
2360 shape->SetLocked(
true );
2365 Expecting(
"layer, width, fill, tstamp, locked or status" );
2373 if( shape->GetWidth() == 0
2374 && ( shape->GetShape() ==
S_RECT || shape->GetShape() ==
S_CIRCLE ) )
2376 shape->SetFilled(
true );
2381 shape->SetFilled(
true );
2387 if( shape->GetWidth() <= 0 && !shape->IsFilled() )
2392 return shape.release();
2398 wxCHECK_MSG( CurTok() == T_gr_text,
NULL,
2399 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXT." ) );
2403 std::unique_ptr<PCB_TEXT> text = std::make_unique<PCB_TEXT>( m_board );
2404 NeedSYMBOLorNUMBER();
2406 text->SetText( FromUTF8() );
2415 pt.x = parseBoardUnits(
"X coordinate" );
2416 pt.y = parseBoardUnits(
"Y coordinate" );
2417 text->SetTextPos( pt );
2422 if( token == T_NUMBER )
2427 else if( token != T_RIGHT )
2429 Unexpected( CurText() );
2432 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2434 if( token != T_LEFT )
2435 Expecting( T_LEFT );
2442 text->SetLayer( parseBoardItemLayer() );
2448 const_cast<KIID&>( text->m_Uuid ) = CurStrToKIID();
2453 parseEDA_TEXT( (
EDA_TEXT*) text.get() );
2457 Expecting(
"layer, tstamp or effects" );
2461 return text.release();
2467 wxCHECK_MSG( CurTok() == T_dimension,
NULL,
2468 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as DIMENSION." ) );
2472 std::unique_ptr<DIMENSION_BASE> dimension;
2475 if( NextTok() != T_LEFT )
2480 bool isLegacyDimension =
false;
2483 if( token == T_width )
2485 isLegacyDimension =
true;
2486 dimension = std::make_unique<ALIGNED_DIMENSION>(
nullptr );
2487 dimension->SetLineThickness( parseBoardUnits(
"dimension width value" ) );
2492 if( token != T_type )
2493 Expecting( T_type );
2498 dimension = std::make_unique<ALIGNED_DIMENSION>(
nullptr );
2502 dimension = std::make_unique<ORTHOGONAL_DIMENSION>(
nullptr );
2506 dimension = std::make_unique<LEADER>(
nullptr );
2510 dimension = std::make_unique<CENTER_DIMENSION>(
nullptr );
2514 wxFAIL_MSG( wxT(
"Cannot parse unknown dimension type %s" ) +
2515 GetTokenString( CurTok() ) );
2521 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2523 if( token != T_LEFT )
2524 Expecting( T_LEFT );
2531 dimension->SetLayer( parseBoardItemLayer() );
2537 const_cast<KIID&>( dimension->m_Uuid ) = CurStrToKIID();
2544 dimension->Text() = *text;
2547 const_cast<KIID&>( dimension->Text().m_Uuid ) = dimension->
m_Uuid;
2550 dimension->Text().SetTextPos( text->
GetTextPos() );
2552 if( isLegacyDimension )
2556 dimension->SetUnits( units );
2568 parseXY( &point.x, &point.y );
2569 dimension->SetStart( point );
2570 parseXY( &point.x, &point.y );
2571 dimension->SetEnd( point );
2581 wxT(
"Invalid height token" ) );
2582 ALIGNED_DIMENSION* aligned = static_cast<ALIGNED_DIMENSION*>( dimension.get() );
2583 aligned->
SetHeight( parseBoardUnits(
"dimension height value" ) );
2591 wxT(
"Invalid orientation token" ) );
2594 int orientation =
parseInt(
"orthogonal dimension orientation" );
2595 orientation = std::max( 0, std::min( 1, orientation ) );
2596 ortho->SetOrientation( static_cast<ORTHOGONAL_DIMENSION::DIR>( orientation ) );
2603 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2611 NeedSYMBOLorNUMBER();
2612 dimension->SetPrefix( FromUTF8() );
2617 NeedSYMBOLorNUMBER();
2618 dimension->SetSuffix( FromUTF8() );
2624 int mode =
parseInt(
"dimension units mode" );
2625 mode = std::max( 0, std::min( 4, mode ) );
2626 dimension->SetUnitsMode( static_cast<DIM_UNITS_MODE>( mode ) );
2631 case T_units_format:
2633 int format =
parseInt(
"dimension units format" );
2634 format = std::max( 0, std::min( 3, format ) );
2635 dimension->SetUnitsFormat( static_cast<DIM_UNITS_FORMAT>( format ) );
2641 dimension->SetPrecision(
parseInt(
"dimension precision" ) );
2645 case T_override_value:
2646 NeedSYMBOLorNUMBER();
2647 dimension->SetOverrideTextEnabled(
true );
2648 dimension->SetOverrideText( FromUTF8() );
2652 case T_suppress_zeroes:
2653 dimension->SetSuppressZeroes(
true );
2657 Expecting(
"prefix, suffix, units, units_format, precision, override_value, " 2658 "suppress_zeroes" );
2667 dimension->SetKeepTextAligned(
false );
2669 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2677 dimension->SetLineThickness( parseBoardUnits(
"extension line thickness" ) );
2681 case T_arrow_length:
2682 dimension->SetArrowLength( parseBoardUnits(
"arrow length" ) );
2686 case T_text_position_mode:
2688 int mode =
parseInt(
"dimension text position mode" );
2689 mode = std::max( 0, std::min( 3, mode ) );
2690 dimension->SetTextPositionMode( static_cast<DIM_TEXT_POSITION>( mode ) );
2695 case T_extension_height:
2697 ALIGNED_DIMENSION* aligned = dynamic_cast<ALIGNED_DIMENSION*>( dimension.get() );
2698 wxCHECK_MSG( aligned,
nullptr, wxT(
"Invalid extension_height token" ) );
2704 case T_extension_offset:
2705 dimension->SetExtensionOffset( parseBoardUnits(
"extension offset" ) );
2709 case T_keep_text_aligned:
2710 dimension->SetKeepTextAligned(
true );
2716 wxT(
"Invalid text_frame token" ) );
2717 LEADER* leader = static_cast<LEADER*>( dimension.get() );
2719 int textFrame =
parseInt(
"dimension text frame mode" );
2720 textFrame = std::max( 0, std::min( 3, textFrame ) );
2721 leader->SetTextFrame( static_cast<DIM_TEXT_FRAME>( textFrame ) );
2727 Expecting(
"thickness, arrow_length, text_position_mode, extension_height, " 2728 "extension_offset" );
2741 if( token != T_pts )
2746 parseXY( &point.x, &point.y );
2747 dimension->SetStart( point );
2749 parseXY(
nullptr,
nullptr );
2761 if( token != T_pts )
2766 parseXY( &point.x, &point.y );
2767 dimension->SetEnd( point );
2769 parseXY(
nullptr,
nullptr );
2781 if( token == T_pts )
2784 ALIGNED_DIMENSION* aligned = static_cast<ALIGNED_DIMENSION*>( dimension.get() );
2787 wxPoint point1, point2;
2788 parseXY( &point1.x, &point1.y );
2789 parseXY( &point2.x, &point2.y );
2803 if( token != T_pts )
2806 parseXY(
nullptr,
nullptr );
2807 parseXY(
nullptr,
nullptr );
2817 if( token != T_pts )
2820 parseXY(
nullptr,
nullptr );
2821 parseXY(
nullptr,
nullptr );
2831 if( token != T_pts )
2834 parseXY(
nullptr,
nullptr );
2835 parseXY(
nullptr,
nullptr );
2845 if( token != T_pts )
2848 parseXY(
nullptr,
nullptr );
2849 parseXY(
nullptr,
nullptr );
2855 Expecting(
"layer, tstamp, gr_text, feature1, feature2, crossbar, arrow1a, " 2856 "arrow1b, arrow2a, or arrow2b" );
2860 dimension->Update();
2862 return dimension.release();
2870 return parseFOOTPRINT_unchecked( aInitialComments );
2884 wxCHECK_MSG( CurTok() == T_module || CurTok() == T_footprint,
NULL,
2885 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FOOTPRINT." ) );
2893 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>( m_board );
2895 std::map<wxString, wxString> properties;
2897 footprint->SetInitialComments( aInitialComments );
2901 if( !IsSymbol( token ) && token != T_NUMBER )
2902 Expecting(
"symbol|number" );
2909 error.Printf(
_(
"Invalid footprint ID in\nfile: \"%s\"\nline: %d\noffset: %d" ),
2910 CurSource(), CurLineNumber(), CurOffset() );
2914 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2916 if( token == T_LEFT )
2926 int this_version =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
2928 m_requiredVersion = std::max( m_requiredVersion, this_version );
2941 footprint->SetLocked(
true );
2945 footprint->SetIsPlaced(
true );
2960 footprint->SetLastEditTime(
parseHex() );
2966 const_cast<KIID&>( footprint->m_Uuid ) = CurStrToKIID();
2971 pt.x = parseBoardUnits(
"X coordinate" );
2972 pt.y = parseBoardUnits(
"Y coordinate" );
2973 footprint->SetPosition( pt );
2976 if( token == T_NUMBER )
2978 footprint->SetOrientation(
parseDouble() * 10.0 );
2981 else if( token != T_RIGHT )
2983 Expecting( T_RIGHT );
2989 NeedSYMBOLorNUMBER();
2990 footprint->SetDescription( FromUTF8() );
2995 NeedSYMBOLorNUMBER();
2996 footprint->SetKeywords( FromUTF8() );
3001 properties.insert( parseProperty() );
3005 NeedSYMBOLorNUMBER();
3006 footprint->SetPath(
KIID_PATH( FromUTF8() ) );
3010 case T_autoplace_cost90:
3011 footprint->SetPlacementCost90(
parseInt(
"auto place cost at 90 degrees" ) );
3015 case T_autoplace_cost180:
3016 footprint->SetPlacementCost180(
parseInt(
"auto place cost at 180 degrees" ) );
3020 case T_solder_mask_margin:
3021 footprint->SetLocalSolderMaskMargin( parseBoardUnits(
"local solder mask margin value" ) );
3025 case T_solder_paste_margin:
3026 footprint->SetLocalSolderPasteMargin(
3027 parseBoardUnits(
"local solder paste margin value" ) );
3031 case T_solder_paste_ratio:
3032 footprint->SetLocalSolderPasteMarginRatio(
3033 parseDouble(
"local solder paste margin ratio value" ) );
3038 footprint->SetLocalClearance( parseBoardUnits(
"local clearance value" ) );
3042 case T_zone_connect:
3047 case T_thermal_width:
3048 footprint->SetThermalWidth( parseBoardUnits(
"thermal width value" ) );
3053 footprint->SetThermalGap( parseBoardUnits(
"thermal gap value" ) );
3058 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3066 case T_through_hole:
3078 case T_exclude_from_pos_files:
3082 case T_exclude_from_bom:
3087 Expecting(
"through_hole, smd, virtual, board_only, exclude_from_pos_files " 3088 "or exclude_from_bom" );
3095 FP_TEXT* text = parseFP_TEXT();
3098 orientation -= footprint->GetOrientation();
3105 footprint->Reference() = *text;
3106 const_cast<KIID&>( footprint->Reference().m_Uuid ) = text->
m_Uuid;
3111 footprint->Value() = *text;
3112 const_cast<KIID&>( footprint->Value().m_Uuid ) = text->
m_Uuid;
3127 if( std::isnormal( shape->
GetAngle() ) )
3153 PAD* pad = parsePAD( footprint.get() );
3157 pad->
SetPosition( pt + footprint->GetPosition() );
3165 footprint->Add3DModel( model );
3172 ZONE* zone = parseZONE( footprint.get() );
3178 parseGROUP( footprint.get() );
3182 Expecting(
"locked, placed, tedit, tstamp, at, descr, tags, path, " 3183 "autoplace_cost90, autoplace_cost180, solder_mask_margin, " 3184 "solder_paste_margin, solder_paste_ratio, clearance, " 3185 "zone_connect, thermal_width, thermal_gap, attr, fp_text, " 3186 "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, fp_rect, pad, " 3187 "zone, group, generator, version or model" );
3196 if( m_requiredVersion < 20200826 && attributes == 0 )
3200 if( m_requiredVersion < 20210108 )
3202 for(
PAD* pad : footprint->Pads() )
3203 pad->SetLocked( footprint->IsLocked() || footprint->LegacyPadsLocked() );
3206 footprint->SetAttributes( attributes );
3208 footprint->SetFPID( fpid );
3209 footprint->SetProperties( properties );
3211 return footprint.release();
3217 wxCHECK_MSG( CurTok() == T_fp_text,
NULL,
3218 wxString::Format( wxT(
"Cannot parse %s as FP_TEXT at line %d, offset %d." ),
3219 GetTokenString( CurTok() ),
3220 CurLineNumber(), CurOffset() ) );
3222 T token = NextTok();
3224 std::unique_ptr<FP_TEXT> text = std::make_unique<FP_TEXT>(
nullptr );
3244 NeedSYMBOLorNUMBER();
3246 wxString value = FromUTF8();
3247 value.Replace(
"%V",
"${VALUE}" );
3248 value.Replace(
"%R",
"${REFERENCE}" );
3249 text->SetText( value );
3258 pt.x = parseBoardUnits(
"X coordinate" );
3259 pt.y = parseBoardUnits(
"Y coordinate" );
3260 text->SetPos0( pt );
3264 if( CurTok() == T_NUMBER )
3270 if( CurTok() == T_unlocked )
3272 text->SetKeepUpright(
false );
3276 if( CurTok() != T_RIGHT )
3278 Unexpected( CurText() );
3281 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3283 if( token == T_LEFT )
3289 text->SetLayer( parseBoardItemLayer() );
3294 text->SetVisible(
false );
3298 parseEDA_TEXT( (
EDA_TEXT*) text.get() );
3303 const_cast<KIID&>( text->m_Uuid ) = CurStrToKIID();
3308 Expecting(
"layer, hide, effects or tstamp" );
3312 return text.release();
3318 wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve ||
3319 CurTok() == T_fp_rect || CurTok() == T_fp_line || CurTok() == T_fp_poly,
NULL,
3320 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FP_SHAPE." ) );
3325 std::unique_ptr<FP_SHAPE> shape = std::make_unique<FP_SHAPE>(
nullptr );
3330 shape->SetShape(
S_ARC );
3336 if( token != T_start && token != T_center )
3337 Expecting( T_start );
3339 pt.x = parseBoardUnits(
"X coordinate" );
3340 pt.y = parseBoardUnits(
"Y coordinate" );
3341 shape->SetStart0( pt );
3346 if( token != T_end )
3349 pt.x = parseBoardUnits(
"X coordinate" );
3350 pt.y = parseBoardUnits(
"Y coordinate" );
3351 shape->SetEnd0( pt );
3356 if( token != T_angle )
3357 Expecting( T_angle );
3361 shape->SetAngle(
parseDouble(
"segment angle" ) * 10.0 );
3370 if( token != T_center )
3371 Expecting( T_center );
3373 pt.x = parseBoardUnits(
"X coordinate" );
3374 pt.y = parseBoardUnits(
"Y coordinate" );
3375 shape->SetStart0( pt );
3380 if( token != T_end )
3383 pt.x = parseBoardUnits(
"X coordinate" );
3384 pt.y = parseBoardUnits(
"Y coordinate" );
3385 shape->SetEnd0( pt );
3394 if( token != T_pts )
3397 shape->SetStart0( parseXY() );
3398 shape->SetBezier0_C1( parseXY() );
3399 shape->SetBezier0_C2( parseXY() );
3400 shape->SetEnd0( parseXY() );
3405 shape->SetShape(
S_RECT );
3409 if( token != T_start )
3410 Expecting( T_start );
3412 pt.x = parseBoardUnits(
"X coordinate" );
3413 pt.y = parseBoardUnits(
"Y coordinate" );
3414 shape->SetStart0( pt );
3420 if( token != T_end )
3423 pt.x = parseBoardUnits(
"X coordinate" );
3424 pt.y = parseBoardUnits(
"Y coordinate" );
3425 shape->SetEnd0( pt );
3434 if( token != T_start )
3435 Expecting( T_start );
3437 pt.x = parseBoardUnits(
"X coordinate" );
3438 pt.y = parseBoardUnits(
"Y coordinate" );
3439 shape->SetStart0( pt );
3445 if( token != T_end )
3448 pt.x = parseBoardUnits(
"X coordinate" );
3449 pt.y = parseBoardUnits(
"Y coordinate" );
3450 shape->SetEnd0( pt );
3460 if( token != T_pts )
3463 std::vector< wxPoint > pts;
3465 while( (token = NextTok() ) != T_RIGHT )
3466 pts.push_back( parseXY() );
3468 shape->SetPolyPoints( pts );
3473 Expecting(
"fp_arc, fp_circle, fp_curve, fp_line, fp_poly, or fp_rect" );
3476 bool foundFill =
false;
3478 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3480 if( token != T_LEFT )
3481 Expecting( T_LEFT );
3488 shape->SetLayer( parseBoardItemLayer() );
3493 shape->SetWidth( parseBoardUnits( T_width ) );
3499 const_cast<KIID&>( shape->m_Uuid ) = CurStrToKIID();
3506 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3508 if( token == T_LEFT )
3517 shape->SetFilled(
true );
3521 shape->SetFilled(
false );
3525 Expecting(
"yes, none, solid" );
3533 shape->SetStatus( static_cast<STATUS_FLAGS>(
parseHex() ) );
3538 shape->SetLocked(
true );
3543 Expecting(
"layer, width, fill, tstamp, locked, or status" );
3551 if( shape->GetWidth() == 0
3552 && ( shape->GetShape() ==
S_RECT || shape->GetShape() ==
S_CIRCLE ) )
3554 shape->SetFilled(
true );
3559 shape->SetFilled(
true );
3565 if( shape->GetWidth() <= 0 && !shape->IsFilled() )
3570 return shape.release();
3576 wxCHECK_MSG( CurTok() == T_pad,
NULL,
3577 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PAD." ) );
3582 std::unique_ptr<PAD> pad = std::make_unique<PAD>( aParent );
3585 pad->SetKeepTopBottom(
false );
3587 NeedSYMBOLorNUMBER();
3588 pad->SetName( FromUTF8() );
3590 T token = NextTok();
3603 pad->SetDrillSize( wxSize( 0, 0 ) );
3611 pad->SetDrillSize( wxSize( 0, 0 ) );
3614 case T_np_thru_hole:
3619 Expecting(
"thru_hole, smd, connect, or np_thru_hole" );
3653 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
3656 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3658 if( token != T_LEFT )
3659 Expecting( T_LEFT );
3666 sz.SetWidth( parseBoardUnits(
"width value" ) );
3667 sz.SetHeight( parseBoardUnits(
"height value" ) );
3673 pt.x = parseBoardUnits(
"X coordinate" );
3674 pt.y = parseBoardUnits(
"Y coordinate" );
3678 if( token == T_NUMBER )
3683 else if( token != T_RIGHT )
3685 Expecting(
") or angle value" );
3693 delta.SetWidth( parseBoardUnits(
"rectangle delta width" ) );
3694 delta.SetHeight( parseBoardUnits(
"rectangle delta height" ) );
3695 pad->SetDelta( delta );
3702 bool haveWidth =
false;
3703 wxSize drillSize = pad->GetDrillSize();
3705 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3707 if( token == T_LEFT )
3720 drillSize.SetWidth( parseBoardUnits() );
3723 drillSize.SetHeight( drillSize.GetWidth() );
3728 drillSize.SetHeight( parseBoardUnits() );
3735 pt.x = parseBoardUnits(
"drill offset x" );
3736 pt.y = parseBoardUnits(
"drill offset y" );
3737 pad->SetOffset( pt );
3742 Expecting(
"oval, size, or offset" );
3751 pad->SetDrillSize( drillSize );
3753 pad->SetDrillSize( wxSize( 0, 0 ) );
3760 LSET layerMask = parseBoardItemLayersAsMask();
3761 pad->SetLayerSet( layerMask );
3766 if( ! pad->SetNetCode( getNetCode(
parseInt(
"net number" ) ),
true ) )
3777 NeedSYMBOLorNUMBER();
3780 if( m_board && pad->GetNetCode() > 0 &&
3781 FromUTF8() != m_board->FindNet( pad->GetNetCode() )->GetNetname() )
3797 NeedSYMBOLorNUMBER();
3798 pad->SetPinFunction( FromUTF8() );
3803 NeedSYMBOLorNUMBER();
3804 pad->SetPinType( FromUTF8() );
3809 pad->SetPadToDieLength( parseBoardUnits( T_die_length ) );
3813 case T_solder_mask_margin:
3814 pad->SetLocalSolderMaskMargin( parseBoardUnits( T_solder_mask_margin ) );
3818 case T_solder_paste_margin:
3819 pad->SetLocalSolderPasteMargin( parseBoardUnits( T_solder_paste_margin ) );
3823 case T_solder_paste_margin_ratio:
3824 pad->SetLocalSolderPasteMarginRatio(
3825 parseDouble(
"pad local solder paste margin ratio value" ) );
3830 pad->SetLocalClearance( parseBoardUnits(
"local clearance value" ) );
3834 case T_zone_connect:
3839 case T_thermal_width:
3840 pad->SetThermalSpokeWidth( parseBoardUnits( T_thermal_width ) );
3845 pad->SetThermalGap( parseBoardUnits( T_thermal_gap ) );
3849 case T_roundrect_rratio:
3850 pad->SetRoundRectRadiusRatio(
parseDouble(
"roundrect radius ratio" ) );
3854 case T_chamfer_ratio:
3855 pad->SetChamferRectRatio(
parseDouble(
"chamfer ratio" ) );
3857 if( pad->GetChamferRectRatio() > 0 )
3866 bool end_list =
false;
3885 case T_bottom_right:
3890 pad->SetChamferPositions( chamfers );
3895 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or chamfer_bottom_right" );
3906 while( token != T_RIGHT )
3912 case T_pad_prop_bga:
3916 case T_pad_prop_fiducial_glob:
3920 case T_pad_prop_fiducial_loc:
3924 case T_pad_prop_testpoint:
3928 case T_pad_prop_castellated:
3932 case T_pad_prop_heatsink:
3944 #if 0 // Currently: skip unknown property 3945 Expecting(
"pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc" 3946 " pad_prop_heatsink or pad_prop_castellated" );
3955 parsePAD_option( pad.get() );
3959 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3961 if( token == T_LEFT )
3973 dummysegm = parsePCB_SHAPE();
3979 dummysegm = parsePCB_SHAPE();
3980 pad->AddPrimitiveSegment( dummysegm->
GetStart(), dummysegm->
GetEnd(),
3985 dummysegm = parsePCB_SHAPE();
3991 dummysegm = parsePCB_SHAPE();
3992 pad->AddPrimitiveRect( dummysegm->
GetStart(), dummysegm->
GetEnd(),
3998 dummysegm = parsePCB_SHAPE();
4004 dummysegm = parsePCB_SHAPE();
4005 pad->AddPrimitiveCurve( dummysegm->
GetStart(), dummysegm->
GetEnd(),
4011 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect or gr_poly" );
4019 case T_remove_unused_layers:
4020 pad->SetRemoveUnconnected(
true );
4024 case T_keep_end_layers:
4025 pad->SetKeepTopBottom(
true );
4030 pad->SetLocked(
true );
4036 const_cast<KIID&>( pad->m_Uuid ) = CurStrToKIID();
4041 Expecting(
"at, locked, drill, layers, net, die_length, roundrect_rratio, " 4042 "solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, " 4043 "clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, " 4044 "pinfunction, pintype, zone_connect, thermal_width, or thermal_gap" );
4048 return pad.release();
4055 for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
4057 if( token != T_LEFT )
4058 Expecting( T_LEFT );
4112 while( (token = NextTok() ) != T_RIGHT )
4128 wxCHECK_RET( CurTok() == T_group,
4129 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
4136 groupInfo.
parent = aParent;
4140 if( token != T_LEFT )
4144 if( !IsSymbol( token ) )
4147 groupInfo.
name = FromUTF8();
4159 groupInfo.
uuid = CurStrToKIID();
4165 if( token != T_members )
4167 Expecting( T_members );
4170 while( ( token = NextTok() ) != T_RIGHT )
4175 KIID uuid( CurStr() );
4185 wxCHECK_MSG( CurTok() == T_arc,
NULL,
4186 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ARC." ) );
4191 std::unique_ptr<ARC> arc = std::make_unique<ARC>( m_board );
4193 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4195 if( token != T_LEFT )
4196 Expecting( T_LEFT );
4203 pt.x = parseBoardUnits(
"start x" );
4204 pt.y = parseBoardUnits(
"start y" );
4205 arc->SetStart( pt );
4209 pt.x = parseBoardUnits(
"mid x" );
4210 pt.y = parseBoardUnits(
"mid y" );
4215 pt.x = parseBoardUnits(
"end x" );
4216 pt.y = parseBoardUnits(
"end y" );
4221 arc->SetWidth( parseBoardUnits(
"width" ) );
4225 arc->SetLayer( parseBoardItemLayer() );
4229 if( !arc->SetNetCode( getNetCode(
parseInt(
"net number" ) ),
true ) )
4231 _(
"Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ), CurSource(),
4232 CurLineNumber(), CurOffset() ) );
4237 const_cast<KIID&>( arc->m_Uuid ) = CurStrToKIID();
4242 arc->SetStatus( static_cast<STATUS_FLAGS>(
parseHex() ) );
4246 arc->SetLocked(
true );
4250 Expecting(
"start, mid, end, width, layer, net, tstamp, or status" );
4256 return arc.release();
4262 wxCHECK_MSG( CurTok() == T_segment,
NULL,
4263 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as TRACK." ) );
4268 std::unique_ptr<TRACK> track = std::make_unique<TRACK>( m_board );
4270 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4272 if( token != T_LEFT )
4273 Expecting( T_LEFT );
4280 pt.x = parseBoardUnits(
"start x" );
4281 pt.y = parseBoardUnits(
"start y" );
4282 track->SetStart( pt );
4286 pt.x = parseBoardUnits(
"end x" );
4287 pt.y = parseBoardUnits(
"end y" );
4288 track->SetEnd( pt );
4292 track->SetWidth( parseBoardUnits(
"width" ) );
4296 track->SetLayer( parseBoardItemLayer() );
4300 if( !track->SetNetCode( getNetCode(
parseInt(
"net number" ) ),
true ) )
4302 _(
"Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ), CurSource(),
4303 CurLineNumber(), CurOffset() ) );
4308 const_cast<KIID&>( track->m_Uuid ) = CurStrToKIID();
4313 track->SetStatus( static_cast<STATUS_FLAGS>(
parseHex() ) );
4317 track->SetLocked(
true );
4321 Expecting(
"start, end, width, layer, net, tstamp, or locked" );
4327 return track.release();
4333 wxCHECK_MSG( CurTok() == T_via,
NULL,
4334 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as VIA." ) );
4339 std::unique_ptr<VIA> via = std::make_unique<VIA>( m_board );
4341 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4343 if( token == T_LEFT )
4357 pt.x = parseBoardUnits(
"start x" );
4358 pt.y = parseBoardUnits(
"start y" );
4359 via->SetStart( pt );
4365 via->SetWidth( parseBoardUnits(
"via width" ) );
4370 via->SetDrill( parseBoardUnits(
"drill diameter" ) );
4378 layer1 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
4380 layer2 = lookUpLayer<PCB_LAYER_ID>( m_layerIndices );
4381 via->SetLayerPair( layer1, layer2 );
4387 if( !via->SetNetCode( getNetCode(
parseInt(
"net number" ) ),
true ) )
4401 case T_remove_unused_layers:
4402 via->SetRemoveUnconnected(
true );
4406 case T_keep_end_layers:
4407 via->SetKeepTopBottom(
true );
4413 const_cast<KIID&>( via->m_Uuid ) = CurStrToKIID();
4419 via->SetStatus( static_cast<STATUS_FLAGS>(
parseHex() ) );
4424 via->SetLocked(
true );
4434 Expecting(
"blind, micro, at, size, drill, layers, net, free, tstamp, or status" );
4438 return via.release();
4444 wxCHECK_MSG( CurTok() == T_zone,
NULL,
4445 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) +
4446 wxT(
" as ZONE." ) );
4454 wxString netnameFromfile;
4457 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
4458 bool inFootprint =
false;
4460 bool addedFilledPolygons =
false;
4462 if( dynamic_cast<FOOTPRINT*>( aParent ) )
4465 std::unique_ptr<ZONE> zone;
4468 zone = std::make_unique<FP_ZONE>( aParent );
4470 zone = std::make_unique<ZONE>( aParent );
4472 zone->SetPriority( 0 );
4474 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4476 if( token == T_LEFT )
4485 tmp = getNetCode(
parseInt(
"net number" ) );
4490 if( !zone->SetNetCode( tmp,
true ) )
4492 _(
"Invalid net ID in\nfile: \"%s\"\nline: %d\noffset: %d" ), CurSource(),
4493 CurLineNumber(), CurOffset() ) );
4499 NeedSYMBOLorNUMBER();
4500 netnameFromfile = FromUTF8();
4505 zone->SetLayer( parseBoardItemLayer() );
4510 zone->SetLayerSet( parseBoardItemLayersAsMask() );
4515 const_cast<KIID&>( zone->m_Uuid ) = CurStrToKIID();
4522 if( token != T_none && token != T_edge && token != T_full )
4523 Expecting(
"none, edge, or full" );
4533 hatchPitch = parseBoardUnits(
"hatch pitch" );
4538 zone->SetPriority(
parseInt(
"zone priority" ) );
4542 case T_connect_pads:
4543 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4545 if( token == T_LEFT )
4558 case T_thru_hole_only:
4563 zone->SetLocalClearance( parseBoardUnits(
"zone clearance" ) );
4568 Expecting(
"yes, no, or clearance" );
4574 case T_min_thickness:
4575 zone->SetMinThickness( parseBoardUnits( T_min_thickness ) );
4579 case T_filled_areas_thickness:
4580 zone->SetFillVersion( parseBool() ? 5 : 6 );
4585 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4587 if( token == T_LEFT )
4593 zone->SetIsFilled(
true );
4599 if( token != T_segment && token != T_hatch && token != T_polygon )
4600 Expecting(
"segment, hatch or polygon" );
4602 if( token == T_segment )
4605 if( m_showLegacyZoneWarning )
4608 _(
"The legacy segment fill mode is no longer supported.\n" 4609 "Convert zones to polygon fills?"),
4610 _(
"Legacy Zone Warning" ),
4611 wxYES_NO | wxICON_WARNING );
4618 m_showLegacyZoneWarning =
false;
4622 m_board->SetModified();
4624 else if( token == T_hatch )
4636 case T_hatch_thickness:
4637 zone->SetHatchThickness( parseBoardUnits( T_hatch_thickness ) );
4642 zone->SetHatchGap( parseBoardUnits( T_hatch_gap ) );
4646 case T_hatch_orientation:
4647 zone->SetHatchOrientation(
parseDouble( T_hatch_orientation ) );
4651 case T_hatch_smoothing_level:
4652 zone->SetHatchSmoothingLevel(
parseDouble( T_hatch_smoothing_level ) );
4656 case T_hatch_smoothing_value:
4657 zone->SetHatchSmoothingValue(
parseDouble( T_hatch_smoothing_value ) );
4661 case T_hatch_border_algorithm:
4664 if( token != T_hatch_thickness && token != T_min_thickness )
4665 Expecting(
"hatch_thickness or min_thickness" );
4667 zone->SetHatchBorderAlgorithm( token == T_hatch_thickness ? 1 : 0 );
4671 case T_hatch_min_hole_area:
4672 zone->SetHatchHoleMinArea(
parseDouble( T_hatch_min_hole_area ) );
4676 case T_arc_segments:
4677 static_cast<void>(
parseInt(
"arc segment count" ) );
4682 zone->SetThermalReliefGap( parseBoardUnits( T_thermal_gap ) );
4686 case T_thermal_bridge_width:
4687 zone->SetThermalReliefSpokeWidth( parseBoardUnits( T_thermal_bridge_width ) );
4699 if( !zone->GetIsRuleArea() )
4704 if( !zone->GetIsRuleArea() )
4709 Expecting(
"none, chamfer, or fillet" );
4715 tmp = parseBoardUnits(
"corner radius" );
4716 if( !zone->GetIsRuleArea() )
4717 zone->SetCornerRadius( tmp );
4722 case T_island_removal_mode:
4723 tmp =
parseInt(
"island_removal_mode" );
4725 if( tmp >= 0 && tmp <= 2 )
4726 zone->SetIslandRemovalMode( static_cast<ISLAND_REMOVAL_MODE>( tmp ) );
4731 case T_island_area_min:
4733 int area = parseBoardUnits( T_island_area_min );
4734 zone->SetMinIslandArea( area *
IU_PER_MM );
4740 Expecting(
"mode, arc_segments, thermal_gap, thermal_bridge_width, " 4741 "hatch_thickness, hatch_gap, hatch_orientation, " 4742 "hatch_smoothing_level, hatch_smoothing_value, " 4743 "hatch_border_algorithm, hatch_min_hole_area, smoothing, radius, " 4744 "island_removal_mode, or island_area_min" );
4751 zone->SetIsRuleArea(
true );
4754 zone->SetDoNotAllowPads(
false );
4755 zone->SetDoNotAllowFootprints(
false );
4757 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4759 if( token == T_LEFT )
4767 if( token != T_allowed && token != T_not_allowed )
4768 Expecting(
"allowed or not_allowed" );
4769 zone->SetDoNotAllowTracks( token == T_not_allowed );
4775 if( token != T_allowed && token != T_not_allowed )
4776 Expecting(
"allowed or not_allowed" );
4777 zone->SetDoNotAllowVias( token == T_not_allowed );
4783 if( token != T_allowed && token != T_not_allowed )
4784 Expecting(
"allowed or not_allowed" );
4785 zone->SetDoNotAllowCopperPour( token == T_not_allowed );
4791 if( token != T_allowed && token != T_not_allowed )
4792 Expecting(
"allowed or not_allowed" );
4793 zone->SetDoNotAllowPads( token == T_not_allowed );
4799 if( token != T_allowed && token != T_not_allowed )
4800 Expecting(
"allowed or not_allowed" );
4801 zone->SetDoNotAllowFootprints( token == T_not_allowed );
4805 Expecting(
"tracks, vias or copperpour" );
4815 std::vector< wxPoint > corners;
4820 if( token != T_pts )
4823 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4825 corners.push_back( parseXY() );
4832 zone->AddPolygon( corners );
4836 case T_filled_polygon:
4842 if( token == T_layer )
4844 filledLayer = parseBoardItemLayer();
4848 if( token != T_LEFT )
4849 Expecting( T_LEFT );
4855 filledLayer = zone->GetLayer();
4858 bool island =
false;
4860 if( token == T_island )
4868 if( token != T_pts )
4871 if( !pts.count( filledLayer ) )
4879 zone->SetIsIsland( filledLayer, idx );
4881 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4883 poly.
Append( parseXY() );
4888 addedFilledPolygons |= !poly.
IsEmpty();
4892 case T_fill_segments:
4896 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4898 if( token != T_LEFT )
4899 Expecting( T_LEFT );
4903 if( token == T_layer )
4905 filledLayer = parseBoardItemLayer();
4909 if( token != T_LEFT )
4910 Expecting( T_LEFT );
4916 filledLayer = zone->GetLayer();
4919 if( token != T_pts )
4922 SEG segment( parseXY(), parseXY() );
4924 segs.push_back( segment );
4927 zone->SetFillSegments( filledLayer, segs );
4934 zone->SetZoneName( FromUTF8() );
4940 Expecting(
"net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, " 4941 "fill, polygon, filled_polygon, fill_segments, or name" );
4945 if( zone->GetNumCorners() > 2 )
4947 if( !zone->IsOnCopperLayer() )
4954 zone->SetBorderDisplayStyle( hatchStyle, hatchPitch,
true );
4957 if( addedFilledPolygons )
4959 for(
auto& pair : pts )
4960 zone->SetFilledPolysList( pair.first, pair.second );
4962 zone->CalculateFilledArea();
4968 bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsRuleArea();
4974 if( zone_has_net && ( zone->GetNet()->GetNetname() != netnameFromfile ) )
4979 NETINFO_ITEM* net = m_board->FindNet( netnameFromfile );
4987 int newnetcode = m_board->GetNetCount();
4988 net =
new NETINFO_ITEM( m_board, netnameFromfile, newnetcode );
4989 m_board->Add( net );
4992 pushValueIntoMap( newnetcode, net->
GetNetCode() );
4999 zone->SetNeedRefill(
false );
5001 return zone.release();
5007 wxCHECK_MSG( CurTok() == T_target,
NULL,
5008 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TARGET." ) );
5013 std::unique_ptr<PCB_TARGET> target = std::make_unique<PCB_TARGET>(
nullptr );
5015 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5017 if( token == T_LEFT )
5023 target->SetShape( 1 );
5027 target->SetShape( 0 );
5031 pt.x = parseBoardUnits(
"target x position" );
5032 pt.y = parseBoardUnits(
"target y position" );
5033 target->SetPosition( pt );
5038 target->SetSize( parseBoardUnits(
"target size" ) );
5043 target->SetWidth( parseBoardUnits(
"target thickness" ) );
5048 target->SetLayer( parseBoardItemLayer() );
5054 const_cast<KIID&>( target->m_Uuid ) = CurStrToKIID();
5059 Expecting(
"x, plus, at, size, width, layer or tstamp" );
5063 return target.release();
5074 m_resetKIIDMap.insert( std::make_pair( CurStr(), aId ) );
5078 aId =
KIID( CurStr() );
void SetMirrored(bool isMirrored)
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
int Mm2mils(double x)
Convert mm to mils.
ZONE_CONNECTION
How pads are covered by copper in zone.
Container to handle a stock of specific vias each with unique diameter and drill sizes in the BOARD c...
int m_ZoneFillVersion
Option to select different fill algorithms.
bool AddItem(BOARD_ITEM *aItem)
Add item to group.
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
void SetBrdLayerId(PCB_LAYER_ID aBrdLayerId)
void SetTypeName(const wxString &aName)
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
class ALIGNED_DIMENSION, a linear dimension (graphic item)
class LEADER, a leader dimension (graphic item)
LSET parseBoardItemLayersAsMask()
Parse the layers definition of a BOARD_ITEM object.
class FP_TEXT, text in a footprint
wxPoint m_GridOrigin
origin for grid offsets
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
no special fabrication property
wxString m_name
The canonical name of the layer.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
this class manage the layers needed to make a physical board they are solder mask,...
This file is part of the common library.
PCB_PLOT_PARAMS_PARSER is the parser class for PCB_PLOT_PARAMS.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
std::vector< int > m_TrackWidthList
class PCB_GROUP, a set of BOARD_ITEMs
void SetRevision(const wxString &aRevision)
wxString m_FinishType
The name of external copper finish.
static constexpr double IU_PER_MM
Mock up a conversion function.
A set of BOARD_ITEMs (i.e., without duplicates).
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
bool m_EdgePlating
True if the edge board is plated.
void SetTextAngle(double aAngle) override
a fiducial (usually a smd) for the full board
the 3d code uses this value
static uint32_t parseHex(LINE_READER &aReader, const char *aLine, const char **aOutput=NULL)
Parse an ASCII hex integer string with possible leading whitespace into a long integer and updates th...
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
LAYER_T m_type
The type of the layer.
void SetItalic(bool isItalic)
std::vector< KIID > memberUuids
BS_EDGE_CONNECTOR_CONSTRAINTS m_EdgeConnectorConstraints
If the board has edge connector cards, some constrains can be specified in job file: BS_EDGE_CONNECTO...
void SetAnchorPadShape(PAD_SHAPE_T aShape)
Set the shape of the anchor pad for custom shaped pads.
Smd pad, appears on the solder paste layer (default)
wxPoint parseXY()
Parse a coordinate pair (xy X Y) in board units (mm).
polygon (not yet used for tracks, but could be in microwave apps)
void SetVisible(bool aVisible)
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.
void createOldLayerMapping(std::unordered_map< std::string, std::string > &aMap)
Create a mapping from the (short-lived) bug where layer names were translated.
bool m_CastellatedPads
True if castellated pads exist.
int m_DimensionPrecision
Number of digits after the decimal.
double GetTextAngle() const
#define DEFAULT_LINE_WIDTH
void SetDrawCoord()
Set relative coordinates.
static double parseDouble(LINE_READER &aReader, const char *aLine, const char **aOutput=NULL)
Parses an ASCII point string with possible leading whitespace into a double precision floating point ...
Smd pad, used in BGA footprints.
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
wxString AsString() const
class FP_SHAPE, a footprint edge
void parseEDA_TEXT(EDA_TEXT *aText)
Parse the common settings for any object derived from EDA_TEXT.
static const wxChar Custom[]
"User" defined page type
void SetTextSize(const wxSize &aNewSize)
void SetSize(const wxSize &aSize)
PCB_SHAPE * parsePCB_SHAPE()
void RotatePoint(int *pX, int *pY, double angle)
like PAD_PTH, but not plated mechanical use only, no connection allowed
a pad used as heat sink, usually in SMD footprints
segment with non rounded ends
A logical library item identifier and consists of various portions much like a URI.
Hold the information shown in the lower right corner of a plot, printout, or editing view.
VECTOR3D m_Offset
3D model offset (mm)
Container to handle a stock of specific differential pairs each with unique track width,...
void SetViaDrill(int aSize)
virtual void SetParent(EDA_ITEM *aParent)
DIM_UNITS_MODE m_DimensionUnitsMode
This file contains miscellaneous commonly used macros and functions.
wxPoint GetArcStart() const
a pad with a castellated through hole
FP_SHAPE * parseFP_SHAPE()
void SetExtensionHeight(int aHeight)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
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.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
wxSize m_TextSize[LAYER_CLASS_COUNT]
void skipCurrent()
Skip the current token level, i.e search for the RIGHT parenthesis which closes the current descripti...
bool m_HasDielectricConstrains
True if some layers have impedance controlled tracks or have specific constrains for micro-wave appli...
const std::vector< wxPoint > BuildPolyPointsList() const
Build and return the list of corners in a std::vector<wxPoint> It must be used only to convert the SH...
bool parsePAD_option(PAD *aPad)
bool m_Show
Include model in rendering.
PCB_LAYER_ID
A quick note on layer IDs:
wxString GetRequiredVersion()
Return a string representing the version of KiCad required to open this file.
int m_TextThickness[LAYER_CLASS_COUNT]
void SetHeight(int aHeight)
Sets the distance from the feature points to the crossbar line.
LSET is a set of PCB_LAYER_IDs.
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
pads are covered by copper
void FetchUnitsFromString(const wxString &aTextValue, EDA_UNITS &aUnits)
Function FetchUnitsFromString writes any unit info found in the string to aUnits.
void SetComment(int aIdx, const wxString &aComment)
std::pair< wxString, wxString > parseProperty()
static int GetDefaultHatchPitch()
Function GetDefaultHatchPitchMils.
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
#define MIN_VISIBILITY_MASK
A leader is a dimension-like object pointing to a specific point.
void SetClearance(int aClearance)
TEXT_TYPE GetType() const
Represent a set of closed polygons.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetDielectricLayerId(int aLayerId)
PCB_TEXT * parsePCB_TEXT()
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
void SetDrillSize(const wxSize &aSize)
A collection of nets and the parameters used to route or test these nets.
void SetNetCode(int aNetCode)
wxPoint GetCenter() const override
This defaults to the center of the bounding box if not overridden.
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
An orthogonal dimension is like an aligned dimension, but the extension lines are locked to the X or ...
bool m_TextItalic[LAYER_CLASS_COUNT]
PCB_TARGET * parsePCB_TARGET()
PCB_LAYER_ID parseBoardItemLayer()
Parse the layer definition of a BOARD_ITEM object.
void SetCompany(const wxString &aCompany)
static LSET InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
static GAL_SET DefaultVisible()
FOOTPRINT * parseFOOTPRINT(wxArrayString *aInitialComments=0)
PAD * parsePAD(FOOTPRINT *aParent=NULL)
FOOTPRINT * parseFOOTPRINT_unchecked(wxArrayString *aInitialComments=0)
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
Function SetLayerPair For a via m_layer contains the top layer, the other layer is in m_bottomLayer.
void SetMaterial(const wxString &aName, int aDielectricSubLayer=0)
ZONE handles a list of polygons defining a copper zone.
wxString m_userName
The user defined name of the layer.
int m_CopperEdgeClearance
void SetuViaDiameter(int aSize)
#define BOARD_FILE_HOST_VERSION
Earlier files than this include the host tag.
static LAYER_T ParseType(const char *aType)
Convert a string to a LAYER_T.
void SetCustomShapeInZoneOpt(CUST_PAD_SHAPE_IN_ZONE aOption)
Set the option for the custom pad shape to use as clearance area in copper zones.
static int parseInt(LINE_READER &aReader, const char *aLine, const char **aOutput=NULL)
Parse an ASCII integer string with possible leading whitespace into an integer and updates the pointe...
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
void SetTitle(const wxString &aTitle)
PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board.
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
int NewOutline()
Creates a new hole in a given outline.
this class manage one layer needed to make a physical board it can be a solder mask,...
int m_LineThickness[LAYER_CLASS_COUNT]
void SetHeightMils(int aHeightInMils)
void SetEpsilonR(double aEpsilon, int aDielectricSubLayer=0)
void UpdateHeight(const wxPoint &aCrossbarStart, const wxPoint &aCrossbarEnd)
Updates stored height basing on points coordinates.
void AddDielectricPrms(int aDielectricPrmsIdx)
true if this stackup item must be taken in account, false to ignore it.
Thermal relief only for THT pads.
void parseDefaults(BOARD_DESIGN_SETTINGS &aSettings)
void SetThickness(int aThickness, int aDielectricSubLayer=0)
static const int ORPHANED
NETINFO_ITEM meaning that there was no net assigned for an item, as there was no board storing net li...
int LAYER_NUM
This can be replaced with int and removed.
class FOOTPRINT, a footprint
ZONE_SETTINGS handles zones parameters.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
wxString m_Filename
The 3D shape filename in 3D library.
void parseGROUP(BOARD_ITEM *aParent)
BOARD * parseBOARD_unchecked()
void parseLayer(LAYER *aLayer)
const wxPoint & GetPos0() const
void SetThicknessLocked(bool aLocked, int aDielectricSubLayer=0)
Handle the data for a net.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
A filename or source description, a problem input line, a line number, a byte offset,...
void parseDefaultTextDims(BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
a fiducial (usually a smd) local to the parent footprint
VECTOR3D m_Rotation
3D model rotation (degrees)
void SetuViaDrill(int aSize)
std::vector< SEG > ZONE_SEGMENT_FILL
Container to hold information pertinent to a layer of a BOARD.
Information pertinent to a Pcbnew printed circuit board.
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
const wxPoint & GetBezControl2() const
void parseGeneralSection()
void SetPosition(const wxPoint &aPos) override
void init()
Clear and re-establish m_layerMap with the default layer names.
void SetWidthMils(int aWidthInMils)
class ZONE, managed by a footprint
VIATYPE GetViaType() const
void pushValueIntoMap(int aIndex, int aValue)
Add aValue value in netcode mapping (m_netCodes) at aIndex.
std::vector< VIA_DIMENSION > m_ViasDimensionsList
double parseDouble()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
void SetViaDiameter(int aDia)
const wxPoint & GetTextPos() const
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
class ORTHOGONAL_DIMENSION, a linear dimension constrained to x/y
class VIA, a via (like a track segment on a copper layer)
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Pcbnew s-expression file format parser definition.
ZONE_SETTINGS & GetDefaultZoneSettings()
bool m_MicroViasAllowed
true to allow micro vias
void SetColor(const wxString &aColorName)
Abstract interface for BOARD_ITEMs capable of storing other items inside.
int m_number
The layer ID.
void Add(BOARD_STACKUP_ITEM *aItem)
Add a new item in stackup layer.
double m_SolderPasteMarginRatio
For better understanding of the points that make a dimension:
void Parse(PCB_PLOT_PARAMS_PARSER *aParser)
BOARD_ITEM_CONTAINER * GetParent() const
DIMENSION_BASE * parseDIMENSION()
static constexpr int Millimeter2iu(double mm)
void resolveGroups(BOARD_ITEM *aParent)
Called after parsing a footprint definition or board to build the group membership lists.
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
#define THROW_IO_ERROR(msg)
void SetLossTangent(double aTg, int aDielectricSubLayer=0)
const wxPoint & GetBezControl1() const
virtual const wxString & GetText() const
Return the string associated with the text object.
wxPoint m_AuxOrigin
origin for plot exports
FP_3DMODEL * parse3DModel()
bool m_TextUpright[LAYER_CLASS_COUNT]
T lookUpLayer(const M &aMap)
Parse the current token for the layer definition of a BOARD_ITEM object.
void SetName(wxString aName)
KICAD_T Type() const
Returns the type of object.
Container for design settings for a BOARD object.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
ZONE * parseZONE(BOARD_ITEM_CONTAINER *aParent)