diff --git a/common/pcb.keywords b/common/pcb.keywords index 59d958bcc2..89438895ac 100644 --- a/common/pcb.keywords +++ b/common/pcb.keywords @@ -60,7 +60,11 @@ crossbar custom outline convexhull +copper_line_width +copper_text_dims +courtyard_line_width date +defaults descr die_length dimension @@ -69,6 +73,8 @@ diff_pair_gap drawings drill edge +edge_clearance +edge_cuts_line_width edge_width effects end @@ -105,6 +111,7 @@ hide italic justify keepout +keep_upright kicad_pcb last_trace_width layer @@ -133,6 +140,8 @@ not_allowed np_thru_hole offset options +other_layers_line_width +other_layers_text_dims oval pad pads @@ -167,6 +176,8 @@ scale segment segment_width setup +silk_line_width +silk_text_dims size smd smoothing @@ -199,6 +210,7 @@ thru_hole_only tstamp unlocked user +user_diff_pair user_trace_width user_via uvia_dia diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index fad959bf74..bd4e83056e 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -515,23 +515,39 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in return false; } - - // 6.0 TODO: some settings didn't make it into the board file in 5.1 so as not to - // change the file format. For 5.1 we must copy them across from the config-initialized - // board. BOARD_DESIGN_SETTINGS& bds = loadedBoard->m_designSettings; - BOARD_DESIGN_SETTINGS& configBds = GetBoard()->GetDesignSettings(); + if( bds.m_CopperEdgeClearance == Millimeter2iu( LEGACY_COPPEREDGECLEARANCE ) ) + { + // 5.1 boards stored some settings in the config so as not to bump the file version. + // These will have been loaded into the config-initialized board, so we copy them + // from there. + BOARD_DESIGN_SETTINGS& configBds = GetBoard()->GetDesignSettings(); + + bds.m_RequireCourtyards = configBds.m_RequireCourtyards; + bds.m_ProhibitOverlappingCourtyards = configBds.m_ProhibitOverlappingCourtyards; + bds.m_HoleToHoleMin = configBds.m_HoleToHoleMin; + bds.m_LineThickness[LAYER_CLASS_OTHERS] = configBds.m_LineThickness[LAYER_CLASS_OTHERS]; + bds.m_TextSize[LAYER_CLASS_OTHERS] = configBds.m_TextSize[LAYER_CLASS_OTHERS]; + bds.m_TextThickness[LAYER_CLASS_OTHERS] = configBds.m_TextThickness[LAYER_CLASS_OTHERS]; + std::copy( configBds.m_TextItalic, configBds.m_TextItalic + 4, bds.m_TextItalic ); + std::copy( configBds.m_TextUpright, configBds.m_TextUpright + 4, bds.m_TextUpright ); + bds.m_DiffPairDimensionsList = configBds.m_DiffPairDimensionsList; + bds.m_CopperEdgeClearance = configBds.m_CopperEdgeClearance; + + // Before we had a copper edge clearance setting, the edge line widths could be used + // as a kludge to control them. So if there's no setting then infer it from the + // edge widths. + if( bds.m_CopperEdgeClearance == Millimeter2iu( LEGACY_COPPEREDGECLEARANCE ) ) + bds.SetCopperEdgeClearance( inferLegacyEdgeClearance( loadedBoard ) ); + } + + // 6.0 TODO: some of the 5.1 settings still haven't moved because they're waiting on + // the new DRC architecture + BOARD_DESIGN_SETTINGS& configBds = GetBoard()->GetDesignSettings(); bds.m_RequireCourtyards = configBds.m_RequireCourtyards; bds.m_ProhibitOverlappingCourtyards = configBds.m_ProhibitOverlappingCourtyards; bds.m_HoleToHoleMin = configBds.m_HoleToHoleMin; - bds.m_LineThickness[LAYER_CLASS_OTHERS] = configBds.m_LineThickness[LAYER_CLASS_OTHERS]; - bds.m_TextSize[LAYER_CLASS_OTHERS] = configBds.m_TextSize[LAYER_CLASS_OTHERS]; - bds.m_TextThickness[LAYER_CLASS_OTHERS] = configBds.m_TextThickness[LAYER_CLASS_OTHERS]; - std::copy( configBds.m_TextItalic, configBds.m_TextItalic + 4, bds.m_TextItalic ); - std::copy( configBds.m_TextUpright, configBds.m_TextUpright + 4, bds.m_TextUpright ); - bds.m_DiffPairDimensionsList = configBds.m_DiffPairDimensionsList; - bds.m_CopperEdgeClearance = configBds.m_CopperEdgeClearance; SetBoard( loadedBoard ); @@ -539,11 +555,6 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in loadedBoard->BuildListOfNets(); loadedBoard->SynchronizeNetsAndNetClasses(); - // If this is a legacy board then we set the copper edge clearance to 1/2 the edge-cut - // line width (which was a legacy kludge for implementing edge clearances). - if( bds.m_CopperEdgeClearance == Millimeter2iu( LEGACY_COPPEREDGECLEARANCE ) ) - bds.SetCopperEdgeClearance( inferLegacyEdgeClearance( loadedBoard ) ); - if( loadedBoard->IsModified() ) OnModify(); else diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 1f5f8b8ac1..6fe82916c3 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -477,10 +477,12 @@ void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const m_out->Print( aNestLevel+1, "(last_trace_width %s)\n", FormatInternalUnits( dsnSettings.GetCurrentTrackWidth() ).c_str() ); - // Save custom tracks width list (the first is not saved here: this is the netclass value + // Save custom track widths list (the first is not saved here: it's the netclass value) for( unsigned ii = 1; ii < dsnSettings.m_TrackWidthList.size(); ii++ ) + { m_out->Print( aNestLevel+1, "(user_trace_width %s)\n", FormatInternalUnits( dsnSettings.m_TrackWidthList[ii] ).c_str() ); + } m_out->Print( aNestLevel+1, "(trace_clearance %s)\n", FormatInternalUnits( dsnSettings.GetDefault()->GetClearance() ).c_str() ); @@ -504,13 +506,21 @@ void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const m_out->Print( aNestLevel+1, "(via_min_drill %s)\n", FormatInternalUnits( dsnSettings.m_ViasMinDrill ).c_str() ); - // Save custom vias diameters list (the first is not saved here: this is - // the netclass value + // Save custom via dimensions list (the first is not saved here: it's the netclass value) for( unsigned ii = 1; ii < dsnSettings.m_ViasDimensionsList.size(); ii++ ) m_out->Print( aNestLevel+1, "(user_via %s %s)\n", FormatInternalUnits( dsnSettings.m_ViasDimensionsList[ii].m_Diameter ).c_str(), FormatInternalUnits( dsnSettings.m_ViasDimensionsList[ii].m_Drill ).c_str() ); + // Save custom diff-pair dimensions (the first is not saved here: it's the netclass value) + for( unsigned ii = 1; ii < dsnSettings.m_DiffPairDimensionsList.size(); ii++ ) + { + m_out->Print( aNestLevel+1, "(user_diff_pair %s %s %s)\n", + FormatInternalUnits( dsnSettings.m_DiffPairDimensionsList[ii].m_Width ).c_str(), + FormatInternalUnits( dsnSettings.m_DiffPairDimensionsList[ii].m_Gap ).c_str(), + FormatInternalUnits( dsnSettings.m_DiffPairDimensionsList[ii].m_ViaGap ).c_str() ); + } + // for old versions compatibility: if( dsnSettings.m_BlindBuriedViaAllowed ) m_out->Print( aNestLevel+1, "(blind_buried_vias_allowed yes)\n" ); @@ -533,28 +543,7 @@ void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const if( dsnSettings.m_ZoneUseNoOutlineInFill ) m_out->Print( aNestLevel+1, "(filled_areas_thickness no)\n" ); - // 6.0 TODO: are we going to update the tokens we save these under? - // 6.0 TODO: need to save the LAYER_CLASS_OTHERS stuff - // 6.0 TODO: need to save the TextItalic and TextUpright settings - - m_out->Print( aNestLevel+1, "(edge_width %s)\n", - FormatInternalUnits( dsnSettings.m_LineThickness[ LAYER_CLASS_EDGES ] ).c_str() ); - - m_out->Print( aNestLevel+1, "(segment_width %s)\n", - FormatInternalUnits( dsnSettings.m_LineThickness[ LAYER_CLASS_COPPER ] ).c_str() ); - m_out->Print( aNestLevel+1, "(pcb_text_width %s)\n", - FormatInternalUnits( dsnSettings.m_TextThickness[ LAYER_CLASS_COPPER ] ).c_str() ); - m_out->Print( aNestLevel+1, "(pcb_text_size %s %s)\n", - FormatInternalUnits( dsnSettings.m_TextSize[ LAYER_CLASS_COPPER ].x ).c_str(), - FormatInternalUnits( dsnSettings.m_TextSize[ LAYER_CLASS_COPPER ].y ).c_str() ); - - m_out->Print( aNestLevel+1, "(mod_edge_width %s)\n", - FormatInternalUnits( dsnSettings.m_LineThickness[ LAYER_CLASS_SILK ] ).c_str() ); - m_out->Print( aNestLevel+1, "(mod_text_size %s %s)\n", - FormatInternalUnits( dsnSettings.m_TextSize[ LAYER_CLASS_SILK ].x ).c_str(), - FormatInternalUnits( dsnSettings.m_TextSize[ LAYER_CLASS_SILK ].y ).c_str() ); - m_out->Print( aNestLevel+1, "(mod_text_width %s)\n", - FormatInternalUnits( dsnSettings.m_TextThickness[ LAYER_CLASS_SILK ] ).c_str() ); + formatDefaults( dsnSettings, aNestLevel+1 ); m_out->Print( aNestLevel+1, "(pad_size %s %s)\n", FormatInternalUnits( dsnSettings.m_Pad_Master.GetSize().x ).c_str(), @@ -595,6 +584,50 @@ void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const } +void PCB_IO::formatDefaults( const BOARD_DESIGN_SETTINGS& aSettings, int aNestLevel ) const +{ + m_out->Print( aNestLevel, "(defaults\n" ); + + m_out->Print( aNestLevel+1, "(edge_clearance %s)\n", + FormatInternalUnits( aSettings.m_CopperEdgeClearance ).c_str() ); + + m_out->Print( aNestLevel+1, "(edge_cuts_line_width %s)\n", + FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_EDGES ] ).c_str() ); + + m_out->Print( aNestLevel+1, "(courtyard_line_width %s)\n", + FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_COURTYARD ] ).c_str() ); + + m_out->Print( aNestLevel+1, "(copper_line_width %s)\n", + FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_COPPER ] ).c_str() ); + m_out->Print( aNestLevel+1, "(copper_text_dims (size %s %s) (thickness %s)%s%s)\n", + FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_COPPER ].x ).c_str(), + FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_COPPER ].y ).c_str(), + FormatInternalUnits( aSettings.m_TextThickness[ LAYER_CLASS_COPPER ] ).c_str(), + aSettings.m_TextItalic[ LAYER_CLASS_COPPER ] ? " italic" : "", + aSettings.m_TextUpright[ LAYER_CLASS_COPPER ] ? " keep_upright" : "" ); + + m_out->Print( aNestLevel+1, "(silk_line_width %s)\n", + FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_SILK ] ).c_str() ); + m_out->Print( aNestLevel+1, "(silk_text_dims (size %s %s) (thickness %s)%s%s)\n", + FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_SILK ].x ).c_str(), + FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_SILK ].y ).c_str(), + FormatInternalUnits( aSettings.m_TextThickness[ LAYER_CLASS_SILK ] ).c_str(), + aSettings.m_TextItalic[ LAYER_CLASS_SILK ] ? " italic" : "", + aSettings.m_TextUpright[ LAYER_CLASS_SILK ] ? " keep_upright" : "" ); + + m_out->Print( aNestLevel+1, "(other_layers_line_width %s)\n", + FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_OTHERS ] ).c_str() ); + m_out->Print( aNestLevel+1, "(other_layers_text_dims (size %s %s) (thickness %s)%s%s)\n", + FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_OTHERS ].x ).c_str(), + FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_OTHERS ].y ).c_str(), + FormatInternalUnits( aSettings.m_TextThickness[ LAYER_CLASS_OTHERS ] ).c_str(), + aSettings.m_TextItalic[ LAYER_CLASS_OTHERS ] ? " italic" : "", + aSettings.m_TextUpright[ LAYER_CLASS_OTHERS ] ? " keep_upright" : "" ); + + m_out->Print( aNestLevel, ")\n" ); +} + + void PCB_IO::formatGeneral( BOARD* aBoard, int aNestLevel ) const { const BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings(); diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h index 4eb39e8b45..c13b5fc46f 100644 --- a/pcbnew/kicad_plugin.h +++ b/pcbnew/kicad_plugin.h @@ -34,6 +34,16 @@ class BOARD_ITEM; class FP_CACHE; class PCB_PARSER; class NETINFO_MAPPING; +class BOARD_DESIGN_SETTINGS; +class DIMENSION; +class EDGE_MODULE; +class DRAWSEGMENT; +class PCB_TARGET; +class D_PAD; +class TEXTE_MODULE; +class TRACK; +class ZONE_CONTAINER; +class TEXTE_PCB; /// Current s-expression file format version. 2 was the last legacy format version. @@ -50,7 +60,8 @@ class NETINFO_MAPPING; //#define SEXPR_BOARD_FILE_VERSION 20171130 // 3D model offset written using "offset" parameter //#define SEXPR_BOARD_FILE_VERSION 20190331 // hatched zones and chamfered round rect pads //#define SEXPR_BOARD_FILE_VERSION 20190421 // curves in custom pads -#define SEXPR_BOARD_FILE_VERSION 20190516 // Remove segment count from zones +//#define SEXPR_BOARD_FILE_VERSION 20190516 // Remove segment count from zones +#define SEXPR_BOARD_FILE_VERSION 20190605 // Add layer defaults #define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names #define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library) @@ -75,18 +86,6 @@ class NETINFO_MAPPING; #define CTL_FOR_BOARD (CTL_OMIT_INITIAL_COMMENTS) -class DIMENSION; -class EDGE_MODULE; -class DRAWSEGMENT; -class PCB_TARGET; -class D_PAD; -class TEXTE_MODULE; -class TRACK; -class ZONE_CONTAINER; -class TEXTE_PCB; - - - /** * Class PCB_IO * is a PLUGIN derivation for saving and loading Pcbnew s-expression formatted files. @@ -205,6 +204,9 @@ protected: /// formats the board setup information void formatSetup( BOARD* aBoard, int aNestLevel = 0 ) const; + /// formats the defaults subsection of the board setup + void formatDefaults( const BOARD_DESIGN_SETTINGS& aSettings, int aNestLevel ) const; + /// formats the General section of the file void formatGeneral( BOARD* aBoard, int aNestLevel = 0 ) const; diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 90ac427f46..73c68bd805 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -1240,7 +1240,7 @@ void PCB_PARSER::parseSetup() { int viaSize = parseBoardUnits( "user via size" ); int viaDrill = parseBoardUnits( "user via drill" ); - designSettings.m_ViasDimensionsList.push_back( VIA_DIMENSION( viaSize, viaDrill ) ); + designSettings.m_ViasDimensionsList.emplace_back( VIA_DIMENSION( viaSize, viaDrill ) ); NeedRIGHT(); } break; @@ -1275,48 +1275,57 @@ void PCB_PARSER::parseSetup() NeedRIGHT(); break; - // 6.0 TODO: change these names, or leave them? - // 6.0 TODO: add LAYER_CLASS_OTHERS read/write - // 6.0 TODO: add m_TextItalic read/write - // 6.0 TODO: add m_TextUpright read/write + case T_user_diff_pair: + { + int width = parseBoardUnits( "user diff-pair width" ); + int gap = parseBoardUnits( "user diff-pair gap" ); + int viaGap = parseBoardUnits( "user diff-pair via gap" ); + designSettings.m_DiffPairDimensionsList.emplace_back( DIFF_PAIR_DIMENSION( width, gap, viaGap ) ); + NeedRIGHT(); + } + break; - case T_segment_width: + case T_segment_width: // note: legacy (pre-6.0) token designSettings.m_LineThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_segment_width ); NeedRIGHT(); break; - case T_edge_width: + case T_edge_width: // note: legacy (pre-6.0) token designSettings.m_LineThickness[ LAYER_CLASS_EDGES ] = parseBoardUnits( T_edge_width ); NeedRIGHT(); break; - case T_mod_edge_width: + case T_mod_edge_width: // note: legacy (pre-6.0) token designSettings.m_LineThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_edge_width ); NeedRIGHT(); break; - case T_pcb_text_width: + case T_pcb_text_width: // note: legacy (pre-6.0) token designSettings.m_TextThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_pcb_text_width ); NeedRIGHT(); break; - case T_mod_text_width: + case T_mod_text_width: // note: legacy (pre-6.0) token designSettings.m_TextThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_text_width ); NeedRIGHT(); break; - case T_pcb_text_size: + case T_pcb_text_size: // note: legacy (pre-6.0) token designSettings.m_TextSize[ LAYER_CLASS_COPPER ].x = parseBoardUnits( "pcb text width" ); designSettings.m_TextSize[ LAYER_CLASS_COPPER ].y = parseBoardUnits( "pcb text height" ); NeedRIGHT(); break; - case T_mod_text_size: + case T_mod_text_size: // note: legacy (pre-6.0) token designSettings.m_TextSize[ LAYER_CLASS_SILK ].x = parseBoardUnits( "module text width" ); designSettings.m_TextSize[ LAYER_CLASS_SILK ].y = parseBoardUnits( "module text height" ); NeedRIGHT(); break; + case T_defaults: + parseDefaults( designSettings ); + break; + case T_pad_size: { wxSize sz; @@ -1415,6 +1424,105 @@ void PCB_PARSER::parseSetup() } +void PCB_PARSER::parseDefaults( BOARD_DESIGN_SETTINGS& designSettings ) +{ + T token; + + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token != T_LEFT ) + Expecting( T_LEFT ); + + token = NextTok(); + + switch( token ) + { + case T_edge_clearance: + designSettings.m_CopperEdgeClearance = parseBoardUnits( T_edge_clearance ); + NeedRIGHT(); + break; + + case T_copper_line_width: + designSettings.m_LineThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( token ); + NeedRIGHT(); + break; + + case T_copper_text_dims: + parseDefaultTextDims( designSettings, LAYER_CLASS_COPPER ); + break; + + case T_courtyard_line_width: + designSettings.m_LineThickness[ LAYER_CLASS_COURTYARD ] = parseBoardUnits( token ); + NeedRIGHT(); + break; + + case T_edge_cuts_line_width: + designSettings.m_LineThickness[ LAYER_CLASS_EDGES ] = parseBoardUnits( token ); + NeedRIGHT(); + break; + + case T_silk_line_width: + designSettings.m_LineThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( token ); + NeedRIGHT(); + break; + + case T_silk_text_dims: + parseDefaultTextDims( designSettings, LAYER_CLASS_SILK ); + break; + + case T_other_layers_line_width: + designSettings.m_LineThickness[ LAYER_CLASS_OTHERS ] = parseBoardUnits( token ); + NeedRIGHT(); + break; + + case T_other_layers_text_dims: + parseDefaultTextDims( designSettings, LAYER_CLASS_OTHERS ); + break; + + default: + Unexpected( CurText() ); + } + } +} + + +void PCB_PARSER::parseDefaultTextDims( BOARD_DESIGN_SETTINGS& aSettings, int aLayer ) +{ + T token; + + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token == T_LEFT ) + token = NextTok(); + + switch( token ) + { + case T_size: + aSettings.m_TextSize[ aLayer ].x = parseBoardUnits( "default text size X" ); + aSettings.m_TextSize[ aLayer ].y = parseBoardUnits( "default text size Y" ); + NeedRIGHT(); + break; + + case T_thickness: + aSettings.m_TextThickness[ aLayer ] = parseBoardUnits( "default text width" ); + NeedRIGHT(); + break; + + case T_italic: + aSettings.m_TextItalic[ aLayer ] = true; + break; + + case T_keep_upright: + aSettings.m_TextUpright[ aLayer ] = true; + break; + + default: + Expecting( "size, thickness, italic or keep_upright" ); + } + } +} + + void PCB_PARSER::parseNETINFO_ITEM() { wxCHECK_RET( CurTok() == T_net, diff --git a/pcbnew/pcb_parser.h b/pcbnew/pcb_parser.h index 0ec787515d..01ed28598b 100644 --- a/pcbnew/pcb_parser.h +++ b/pcbnew/pcb_parser.h @@ -42,6 +42,7 @@ class BOARD; class BOARD_ITEM; class D_PAD; +class BOARD_DESIGN_SETTINGS; class DIMENSION; class DRAWSEGMENT; class EDA_TEXT; @@ -121,6 +122,8 @@ class PCB_PARSER : public PCB_LEXER void parseLayer( LAYER* aLayer ); void parseSetup(); + void parseDefaults( BOARD_DESIGN_SETTINGS& aSettings ); + void parseDefaultTextDims( BOARD_DESIGN_SETTINGS& aSettings, int aLayer ); void parseNETINFO_ITEM(); void parseNETCLASS();