Use 'uuid' (not 'id') in the s-expr PCB groups/generator format

Add some regression tests to check loading of groups and generators
from various versions of the s-expr PCB format.
This commit is contained in:
John Beard 2023-12-15 13:33:34 +00:00
parent 985e590e6f
commit 751c88ef20
17 changed files with 2503 additions and 20 deletions

View File

@ -1943,9 +1943,9 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_GROUP* aGroup, int aNestLevel ) const
if( aGroup->GetItems().empty() ) if( aGroup->GetItems().empty() )
return; return;
m_out->Print( aNestLevel, "(group %s (id \"%s\")\n", m_out->Print( aNestLevel, "(group %s\n", m_out->Quotew( aGroup->GetName() ).c_str() );
m_out->Quotew( aGroup->GetName() ).c_str(),
TO_UTF8( aGroup->m_Uuid.AsString() ) ); KICAD_FORMAT::FormatUuid( m_out, aGroup->m_Uuid );
if( aGroup->IsLocked() ) if( aGroup->IsLocked() )
KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "locked", aGroup->IsLocked() ); KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "locked", aGroup->IsLocked() );
@ -1969,7 +1969,9 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_GROUP* aGroup, int aNestLevel ) const
void PCB_IO_KICAD_SEXPR::format( const PCB_GENERATOR* aGenerator, int aNestLevel ) const void PCB_IO_KICAD_SEXPR::format( const PCB_GENERATOR* aGenerator, int aNestLevel ) const
{ {
m_out->Print( aNestLevel, "(generated (id %s)\n", TO_UTF8( aGenerator->m_Uuid.AsString() ) ); m_out->Print( aNestLevel, "(generated\n" );
KICAD_FORMAT::FormatUuid( m_out, aGenerator->m_Uuid );
m_out->Print( aNestLevel + 1, "(type %s) (name %s)\n", m_out->Print( aNestLevel + 1, "(type %s) (name %s)\n",
TO_UTF8( aGenerator->GetGeneratorType() ), TO_UTF8( aGenerator->GetGeneratorType() ),

View File

@ -146,7 +146,8 @@ class PCB_IO_KICAD_SEXPR; // forward decl
//#define SEXPR_BOARD_FILE_VERSION 20230913 // Custom-shaped-pad spoke templates //#define SEXPR_BOARD_FILE_VERSION 20230913 // Custom-shaped-pad spoke templates
//#define SEXPR_BOARD_FILE_VERSION 20231007 // Generative objects //#define SEXPR_BOARD_FILE_VERSION 20231007 // Generative objects
//#define SEXPR_BOARD_FILE_VERSION 20231014 // V8 file format normalization //#define SEXPR_BOARD_FILE_VERSION 20231014 // V8 file format normalization
#define SEXPR_BOARD_FILE_VERSION 20231212 // Reference image locking/UUIDs, footprint boolean format //#define SEXPR_BOARD_FILE_VERSION 20231212 // Reference image locking/UUIDs, footprint boolean format
#define SEXPR_BOARD_FILE_VERSION 20231231 // Use 'uuid' rather than 'id' for generators and groups
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag #define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting #define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting

View File

@ -5037,7 +5037,9 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseGROUP( BOARD_ITEM* aParent )
switch( token ) switch( token )
{ {
// From formats [20200811, 20231215), 'id' was used instead of 'uuid'
case T_id: case T_id:
case T_uuid:
NextTok(); NextTok();
groupInfo.uuid = CurStrToKIID(); groupInfo.uuid = CurStrToKIID();
NeedRIGHT(); NeedRIGHT();
@ -5055,7 +5057,7 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseGROUP( BOARD_ITEM* aParent )
} }
default: default:
Expecting( "id, locked, or members" ); Expecting( "uuid, locked, or members" );
} }
} }
} }
@ -5078,8 +5080,9 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseGENERATOR( BOARD_ITEM* aParent )
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
if( token != T_id ) // For formats [20231007, 20231215), 'id' was used instead of 'uuid'
Expecting( T_id ); if( token != T_uuid && token != T_id )
Expecting( T_uuid );
NextTok(); NextTok();
genInfo.uuid = CurStrToKIID(); genInfo.uuid = CurStrToKIID();

View File

@ -0,0 +1,125 @@
(kicad_pcb
(version 20231231)
(generator "pcbnew")
(generator_version "7.99")
(general
(thickness 1.6)
(legacy_teardrops no)
)
(paper "A4")
(layers
(0 "F.Cu" signal)
(31 "B.Cu" signal)
(32 "B.Adhes" user "B.Adhesive")
(33 "F.Adhes" user "F.Adhesive")
(34 "B.Paste" user)
(35 "F.Paste" user)
(36 "B.SilkS" user "B.Silkscreen")
(37 "F.SilkS" user "F.Silkscreen")
(38 "B.Mask" user)
(39 "F.Mask" user)
(40 "Dwgs.User" user "User.Drawings")
(41 "Cmts.User" user "User.Comments")
(42 "Eco1.User" user "User.Eco1")
(43 "Eco2.User" user "User.Eco2")
(44 "Edge.Cuts" user)
(45 "Margin" user)
(46 "B.CrtYd" user "B.Courtyard")
(47 "F.CrtYd" user "F.Courtyard")
(48 "B.Fab" user)
(49 "F.Fab" user)
(50 "User.1" user)
(51 "User.2" user)
(52 "User.3" user)
(53 "User.4" user)
(54 "User.5" user)
(55 "User.6" user)
(56 "User.7" user)
(57 "User.8" user)
(58 "User.9" user)
)
(setup
(pad_to_mask_clearance 0)
(allow_soldermask_bridges_in_footprints no)
(pcbplotparams
(layerselection 0x00010fc_ffffffff)
(plot_on_all_layers_selection 0x0000000_00000000)
(disableapertmacros no)
(usegerberextensions no)
(usegerberattributes yes)
(usegerberadvancedattributes yes)
(creategerberjobfile yes)
(dashed_line_dash_ratio 12.000000)
(dashed_line_gap_ratio 3.000000)
(svgprecision 4)
(plotframeref no)
(viasonmask no)
(mode 1)
(useauxorigin no)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(pdf_front_fp_property_popups yes)
(pdf_back_fp_property_popups yes)
(dxfpolygonmode yes)
(dxfimperialunits yes)
(dxfusepcbnewfont yes)
(psnegative no)
(psa4output no)
(plotreference yes)
(plotvalue yes)
(plotfptext yes)
(plotinvisibletext no)
(sketchpadsonfab no)
(subtractmaskfromsilk no)
(outputformat 1)
(mirror no)
(drillshape 1)
(scaleselection 1)
(outputdirectory "")
)
)
(net 0 "")
(gr_rect
(start 137.54 30.055)
(end 143.61 50.985)
(locked yes)
(stroke
(width 0.2)
(type default)
)
(fill none)
(layer "F.Cu")
(uuid "31c575c4-a510-466f-a17b-69828f152bcb")
)
(gr_rect
(start 123.79 32.895)
(end 134.57 47.885)
(locked yes)
(stroke
(width 0.2)
(type default)
)
(fill none)
(layer "F.Cu")
(uuid "7b225496-2d63-45ad-a1bb-01d0f7578455")
)
(gr_text "Simple group of two items"
(at 119.52 25.15 0)
(layer "Cmts.User")
(uuid "2dd7f66b-e965-4c09-bb3f-acef10a77fbe")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
(bold yes)
)
(justify left bottom)
)
)
(group "GroupName"
(uuid "a78cc65c-451e-451e-9147-4460cc669685")
(locked yes)
(members "31c575c4-a510-466f-a17b-69828f152bcb" "7b225496-2d63-45ad-a1bb-01d0f7578455")
)
)

View File

@ -0,0 +1,271 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.049999999999999996,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.09999999999999999,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.09999999999999999,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.09999999999999999,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.5,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.7999999999999999,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.09999999999999999,
"min_via_diameter": 0.5,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "groups_load_save.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "",
"step": "",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"legacy_lib_dir": "",
"legacy_lib_list": []
},
"sheets": [],
"text_variables": {}
}

View File

@ -0,0 +1,125 @@
(kicad_pcb
(version 20231212)
(generator "pcbnew")
(generator_version "7.99")
(general
(thickness 1.6)
(legacy_teardrops no)
)
(paper "A4")
(layers
(0 "F.Cu" signal)
(31 "B.Cu" signal)
(32 "B.Adhes" user "B.Adhesive")
(33 "F.Adhes" user "F.Adhesive")
(34 "B.Paste" user)
(35 "F.Paste" user)
(36 "B.SilkS" user "B.Silkscreen")
(37 "F.SilkS" user "F.Silkscreen")
(38 "B.Mask" user)
(39 "F.Mask" user)
(40 "Dwgs.User" user "User.Drawings")
(41 "Cmts.User" user "User.Comments")
(42 "Eco1.User" user "User.Eco1")
(43 "Eco2.User" user "User.Eco2")
(44 "Edge.Cuts" user)
(45 "Margin" user)
(46 "B.CrtYd" user "B.Courtyard")
(47 "F.CrtYd" user "F.Courtyard")
(48 "B.Fab" user)
(49 "F.Fab" user)
(50 "User.1" user)
(51 "User.2" user)
(52 "User.3" user)
(53 "User.4" user)
(54 "User.5" user)
(55 "User.6" user)
(56 "User.7" user)
(57 "User.8" user)
(58 "User.9" user)
)
(setup
(pad_to_mask_clearance 0)
(allow_soldermask_bridges_in_footprints no)
(pcbplotparams
(layerselection 0x00010fc_ffffffff)
(plot_on_all_layers_selection 0x0000000_00000000)
(disableapertmacros no)
(usegerberextensions no)
(usegerberattributes yes)
(usegerberadvancedattributes yes)
(creategerberjobfile yes)
(dashed_line_dash_ratio 12.000000)
(dashed_line_gap_ratio 3.000000)
(svgprecision 4)
(plotframeref no)
(viasonmask no)
(mode 1)
(useauxorigin no)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(pdf_front_fp_property_popups yes)
(pdf_back_fp_property_popups yes)
(dxfpolygonmode yes)
(dxfimperialunits yes)
(dxfusepcbnewfont yes)
(psnegative no)
(psa4output no)
(plotreference yes)
(plotvalue yes)
(plotfptext yes)
(plotinvisibletext no)
(sketchpadsonfab no)
(subtractmaskfromsilk no)
(outputformat 1)
(mirror no)
(drillshape 1)
(scaleselection 1)
(outputdirectory "")
)
)
(net 0 "")
(gr_rect
(start 137.54 30.055)
(end 143.61 50.985)
(locked yes)
(stroke
(width 0.2)
(type default)
)
(fill none)
(layer "F.Cu")
(uuid "31c575c4-a510-466f-a17b-69828f152bcb")
)
(gr_rect
(start 123.79 32.895)
(end 134.57 47.885)
(locked yes)
(stroke
(width 0.2)
(type default)
)
(fill none)
(layer "F.Cu")
(uuid "7b225496-2d63-45ad-a1bb-01d0f7578455")
)
(gr_text "Simple group of two items"
(at 119.52 25.15 0)
(layer "Cmts.User")
(uuid "2dd7f66b-e965-4c09-bb3f-acef10a77fbe")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
(bold yes)
)
(justify left bottom)
)
)
(group "GroupName"
(id "a78cc65c-451e-451e-9147-4460cc669685")
(locked yes)
(members "31c575c4-a510-466f-a17b-69828f152bcb" "7b225496-2d63-45ad-a1bb-01d0f7578455")
)
)

View File

@ -0,0 +1,573 @@
(kicad_pcb
(version 20231231)
(generator "pcbnew")
(generator_version "7.99")
(general
(thickness 1.6)
(legacy_teardrops no)
)
(paper "A4")
(layers
(0 "F.Cu" signal)
(31 "B.Cu" signal)
(32 "B.Adhes" user "B.Adhesive")
(33 "F.Adhes" user "F.Adhesive")
(34 "B.Paste" user)
(35 "F.Paste" user)
(36 "B.SilkS" user "B.Silkscreen")
(37 "F.SilkS" user "F.Silkscreen")
(38 "B.Mask" user)
(39 "F.Mask" user)
(40 "Dwgs.User" user "User.Drawings")
(41 "Cmts.User" user "User.Comments")
(42 "Eco1.User" user "User.Eco1")
(43 "Eco2.User" user "User.Eco2")
(44 "Edge.Cuts" user)
(45 "Margin" user)
(46 "B.CrtYd" user "B.Courtyard")
(47 "F.CrtYd" user "F.Courtyard")
(48 "B.Fab" user)
(49 "F.Fab" user)
(50 "User.1" user)
(51 "User.2" user)
(52 "User.3" user)
(53 "User.4" user)
(54 "User.5" user)
(55 "User.6" user)
(56 "User.7" user)
(57 "User.8" user)
(58 "User.9" user)
)
(setup
(pad_to_mask_clearance 0)
(allow_soldermask_bridges_in_footprints no)
(pcbplotparams
(layerselection 0x00010fc_ffffffff)
(plot_on_all_layers_selection 0x0000000_00000000)
(disableapertmacros no)
(usegerberextensions no)
(usegerberattributes yes)
(usegerberadvancedattributes yes)
(creategerberjobfile yes)
(dashed_line_dash_ratio 12.000000)
(dashed_line_gap_ratio 3.000000)
(svgprecision 4)
(plotframeref no)
(viasonmask no)
(mode 1)
(useauxorigin no)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(pdf_front_fp_property_popups yes)
(pdf_back_fp_property_popups yes)
(dxfpolygonmode yes)
(dxfimperialunits yes)
(dxfusepcbnewfont yes)
(psnegative no)
(psa4output no)
(plotreference yes)
(plotvalue yes)
(plotfptext yes)
(plotinvisibletext no)
(sketchpadsonfab no)
(subtractmaskfromsilk no)
(outputformat 1)
(mirror no)
(drillshape 1)
(scaleselection 1)
(outputdirectory "")
)
)
(net 0 "")
(gr_text "Example Tuning generator"
(at 105.13 46.81 0)
(layer "Cmts.User")
(uuid "53c1f939-ba9e-4da8-9dfc-8f32e3549f4d")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
(bold yes)
)
(justify left bottom)
)
)
(segment
(start 119.471487 50.14)
(end 119.471487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "23598711-1292-428d-920c-a74be818ad7e")
)
(segment
(start 122.471487 48.44)
(end 122.471487 49.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "32dfa4c2-9427-47a8-bd2d-ceb643557c88")
)
(segment
(start 116.471487 48.44)
(end 116.471487 49.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "44d73d7d-cf4f-4327-b231-2463bdfe4326")
)
(segment
(start 118.271487 50.14)
(end 118.271487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "48626af6-29e2-4f63-9d3e-122aa7b4ab9c")
)
(segment
(start 121.271487 50.14)
(end 121.271487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "4b411291-a17e-456b-a755-a48e9631eb4a")
)
(segment
(start 121.871487 51.84)
(end 121.871487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "4e879df0-63f3-4cb5-9164-ba33f0b14629")
)
(segment
(start 116.471487 49.84)
(end 116.471487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "588a4917-59d3-4955-9add-663bc4767847")
)
(segment
(start 117.071487 51.84)
(end 117.071487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "59b90d87-2f26-45db-9ce8-68ce8720ea38")
)
(segment
(start 123.13735 50.14)
(end 137.31 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "65de65ea-c59a-49b1-9861-84c37ec18480")
)
(segment
(start 118.271487 51.84)
(end 118.271487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "6f4c6cc9-69de-4bc5-af94-c19e9090a86d")
)
(segment
(start 121.871487 50.14)
(end 121.871487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "72c5d2fa-96ad-46fa-b509-ba435bef0d9f")
)
(segment
(start 119.471487 51.84)
(end 119.471487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "9568f820-d1e6-490c-ba36-a4f2bbd6740c")
)
(segment
(start 121.271487 48.44)
(end 121.271487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "9a9a8f38-4d0b-433a-b590-5d7512f8439b")
)
(segment
(start 120.071487 48.44)
(end 120.071487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a33210e6-9f45-4513-9f49-0851a05915d6")
)
(segment
(start 117.671487 48.44)
(end 117.671487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a4375fde-a926-4e9f-bce5-e55f71434880")
)
(segment
(start 115.871487 49.84)
(end 115.871487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a764fcd6-6263-450e-b747-c64338e0d901")
)
(segment
(start 120.671487 50.14)
(end 120.671487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a9194b6b-c1cb-4532-812c-d60b7a2c3e42")
)
(segment
(start 102.24 50.14)
(end 115.571487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "be40dcb4-4ea4-4d02-b4a7-023ff28a179f")
)
(segment
(start 118.871487 48.44)
(end 118.871487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "c05fe201-beaa-4f3d-8f86-2c044c39a7ad")
)
(segment
(start 117.671487 50.14)
(end 117.671487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "c57febd1-a087-4666-84b8-277ae6bc22d2")
)
(segment
(start 120.071487 50.14)
(end 120.071487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "dabeb0f1-d930-4995-8ecf-a4549a0b252f")
)
(segment
(start 118.871487 50.14)
(end 118.871487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "db664cf3-f269-4ad7-a42c-5f1e0f68c331")
)
(segment
(start 120.671487 51.84)
(end 120.671487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "deea7a88-92cb-4b2d-944a-56499ad070bc")
)
(segment
(start 122.771487 50.14)
(end 123.13735 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "ee8ed2c3-24bd-4b28-a241-887d40cca598")
)
(segment
(start 117.071487 50.14)
(end 117.071487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "faa07f56-f9fe-4e13-88c3-8d80b6691460")
)
(arc
(start 117.971487 52.14)
(mid 118.183619 52.052132)
(end 118.271487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "0376a7f9-ca8e-458b-9d43-8cd3a2a6bc63")
)
(arc
(start 115.571487 50.14)
(mid 115.783619 50.052132)
(end 115.871487 49.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "0461661b-2681-445d-844d-36fe87fd5675")
)
(arc
(start 120.371487 52.14)
(mid 120.583619 52.052132)
(end 120.671487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "06764c74-03e5-4cdd-9d3c-66a9449a0b79")
)
(arc
(start 119.471487 48.44)
(mid 119.559355 48.227868)
(end 119.771487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "19d41ad9-cced-4f7a-b477-770f3747302b")
)
(arc
(start 116.471487 51.84)
(mid 116.559355 52.052132)
(end 116.771487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "2f6798f2-7245-45ac-b638-798d5cc07bf0")
)
(arc
(start 122.171487 48.14)
(mid 122.383619 48.227868)
(end 122.471487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "3b913f43-9eae-4c65-9978-5b8d339e4163")
)
(arc
(start 119.771487 48.14)
(mid 119.983619 48.227868)
(end 120.071487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "3d5e09fa-3d6d-4ef1-914a-0f5c228935f9")
)
(arc
(start 116.171487 48.14)
(mid 116.383619 48.227868)
(end 116.471487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "4a64cb98-0cb5-4e84-be7d-331ff151461c")
)
(arc
(start 117.371487 48.14)
(mid 117.583619 48.227868)
(end 117.671487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "71f8bf22-de50-41c8-825f-904f110a02bf")
)
(arc
(start 120.071487 51.84)
(mid 120.159355 52.052132)
(end 120.371487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "7269ec18-3e42-46f7-847b-da594f31ad8f")
)
(arc
(start 118.271487 48.44)
(mid 118.359355 48.227868)
(end 118.571487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "767c8903-fd9f-4b6f-928b-98dd2c7597aa")
)
(arc
(start 121.871487 48.44)
(mid 121.959355 48.227868)
(end 122.171487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "7e47bebe-0dd6-4cfd-94dc-ee99962d4434")
)
(arc
(start 120.971487 48.14)
(mid 121.183619 48.227868)
(end 121.271487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "81aa3b3f-7131-448f-81ce-e2677966b704")
)
(arc
(start 118.871487 51.84)
(mid 118.959355 52.052132)
(end 119.171487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "9059e5ed-2aca-4368-82ba-41b385dc3811")
)
(arc
(start 121.271487 51.84)
(mid 121.359355 52.052132)
(end 121.571487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "91c3b598-b183-4c54-a5ba-e81d86f8b752")
)
(arc
(start 117.671487 51.84)
(mid 117.759355 52.052132)
(end 117.971487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "93331fa0-f088-494f-bb3f-3176a38bbf75")
)
(arc
(start 118.571487 48.14)
(mid 118.783619 48.227868)
(end 118.871487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "93ffb905-f4d4-4d6f-9d14-0d9786a08101")
)
(arc
(start 116.771487 52.14)
(mid 116.983619 52.052132)
(end 117.071487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "9f8c447b-e5c8-4000-a9a1-c72d9bea35fb")
)
(arc
(start 120.671487 48.44)
(mid 120.759355 48.227868)
(end 120.971487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a697b4a2-c596-4045-9f46-e645ac352ae2")
)
(arc
(start 121.571487 52.14)
(mid 121.783619 52.052132)
(end 121.871487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a8d58e65-4b30-4eb5-84c7-aee72c58f2ec")
)
(arc
(start 115.871487 48.44)
(mid 115.959355 48.227868)
(end 116.171487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "b0d4aab8-c57b-40b9-9c8b-1f3eb20c6447")
)
(arc
(start 119.171487 52.14)
(mid 119.383619 52.052132)
(end 119.471487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "bf81b70e-6c92-4fa5-9780-102df6c38109")
)
(arc
(start 117.071487 48.44)
(mid 117.159355 48.227868)
(end 117.371487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "d6d9b09a-5a95-454c-82fb-b8e919d934e0")
)
(arc
(start 122.471487 49.84)
(mid 122.559355 50.052132)
(end 122.771487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "eab2f350-d181-4351-8fe1-1d59f4400931")
)
(generated
(id 4f22a815-3048-42b3-86fa-eb71720d35ae)
(type tuning_pattern)
(name "Tuning Pattern")
(layer "F.Cu")
(base_line
(pts
(xy 115.571487 50.14) (xy 123.13735 50.14)
)
)
(corner_radius_percent 100)
(end
(xy 123.13735 50.14)
)
(initial_side "left")
(last_diff_pair_gap 0.18)
(last_netname "")
(last_status "too_short")
(last_track_width 0.2)
(last_tuning "75.9800 mm (too short)")
(max_amplitude 2)
(min_spacing 0.6)
(origin
(xy 115.571487 50.14)
)
(override_custom_rules no)
(rounded yes)
(single_sided no)
(target_length 100)
(target_length_max 100.1)
(target_length_min 99.9)
(target_skew 0)
(target_skew_max 0.1)
(target_skew_min -0.1)
(tuning_mode "single")
(members 0376a7f9-ca8e-458b-9d43-8cd3a2a6bc63 0461661b-2681-445d-844d-36fe87fd5675
06764c74-03e5-4cdd-9d3c-66a9449a0b79 19d41ad9-cced-4f7a-b477-770f3747302b
23598711-1292-428d-920c-a74be818ad7e 2f6798f2-7245-45ac-b638-798d5cc07bf0
32dfa4c2-9427-47a8-bd2d-ceb643557c88 3b913f43-9eae-4c65-9978-5b8d339e4163
3d5e09fa-3d6d-4ef1-914a-0f5c228935f9 44d73d7d-cf4f-4327-b231-2463bdfe4326
48626af6-29e2-4f63-9d3e-122aa7b4ab9c 4a64cb98-0cb5-4e84-be7d-331ff151461c
4b411291-a17e-456b-a755-a48e9631eb4a 4e879df0-63f3-4cb5-9164-ba33f0b14629
588a4917-59d3-4955-9add-663bc4767847 59b90d87-2f26-45db-9ce8-68ce8720ea38
6f4c6cc9-69de-4bc5-af94-c19e9090a86d 71f8bf22-de50-41c8-825f-904f110a02bf
7269ec18-3e42-46f7-847b-da594f31ad8f 72c5d2fa-96ad-46fa-b509-ba435bef0d9f
767c8903-fd9f-4b6f-928b-98dd2c7597aa 7e47bebe-0dd6-4cfd-94dc-ee99962d4434
81aa3b3f-7131-448f-81ce-e2677966b704 9059e5ed-2aca-4368-82ba-41b385dc3811
91c3b598-b183-4c54-a5ba-e81d86f8b752 93331fa0-f088-494f-bb3f-3176a38bbf75
93ffb905-f4d4-4d6f-9d14-0d9786a08101 9568f820-d1e6-490c-ba36-a4f2bbd6740c
9a9a8f38-4d0b-433a-b590-5d7512f8439b 9f8c447b-e5c8-4000-a9a1-c72d9bea35fb
a33210e6-9f45-4513-9f49-0851a05915d6 a4375fde-a926-4e9f-bce5-e55f71434880
a697b4a2-c596-4045-9f46-e645ac352ae2 a764fcd6-6263-450e-b747-c64338e0d901
a8d58e65-4b30-4eb5-84c7-aee72c58f2ec a9194b6b-c1cb-4532-812c-d60b7a2c3e42
b0d4aab8-c57b-40b9-9c8b-1f3eb20c6447 bf81b70e-6c92-4fa5-9780-102df6c38109
c05fe201-beaa-4f3d-8f86-2c044c39a7ad c57febd1-a087-4666-84b8-277ae6bc22d2
d6d9b09a-5a95-454c-82fb-b8e919d934e0 dabeb0f1-d930-4995-8ecf-a4549a0b252f
db664cf3-f269-4ad7-a42c-5f1e0f68c331 deea7a88-92cb-4b2d-944a-56499ad070bc
eab2f350-d181-4351-8fe1-1d59f4400931 ee8ed2c3-24bd-4b28-a241-887d40cca598
faa07f56-f9fe-4e13-88c3-8d80b6691460
)
)
)

View File

@ -0,0 +1,271 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.049999999999999996,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.09999999999999999,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.09999999999999999,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.09999999999999999,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.5,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.7999999999999999,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.09999999999999999,
"min_via_diameter": 0.5,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "tuning_generators_load_save.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "",
"step": "",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"legacy_lib_dir": "",
"legacy_lib_list": []
},
"sheets": [],
"text_variables": {}
}

View File

@ -0,0 +1,573 @@
(kicad_pcb
(version 20231212)
(generator "pcbnew")
(generator_version "7.99")
(general
(thickness 1.6)
(legacy_teardrops no)
)
(paper "A4")
(layers
(0 "F.Cu" signal)
(31 "B.Cu" signal)
(32 "B.Adhes" user "B.Adhesive")
(33 "F.Adhes" user "F.Adhesive")
(34 "B.Paste" user)
(35 "F.Paste" user)
(36 "B.SilkS" user "B.Silkscreen")
(37 "F.SilkS" user "F.Silkscreen")
(38 "B.Mask" user)
(39 "F.Mask" user)
(40 "Dwgs.User" user "User.Drawings")
(41 "Cmts.User" user "User.Comments")
(42 "Eco1.User" user "User.Eco1")
(43 "Eco2.User" user "User.Eco2")
(44 "Edge.Cuts" user)
(45 "Margin" user)
(46 "B.CrtYd" user "B.Courtyard")
(47 "F.CrtYd" user "F.Courtyard")
(48 "B.Fab" user)
(49 "F.Fab" user)
(50 "User.1" user)
(51 "User.2" user)
(52 "User.3" user)
(53 "User.4" user)
(54 "User.5" user)
(55 "User.6" user)
(56 "User.7" user)
(57 "User.8" user)
(58 "User.9" user)
)
(setup
(pad_to_mask_clearance 0)
(allow_soldermask_bridges_in_footprints no)
(pcbplotparams
(layerselection 0x00010fc_ffffffff)
(plot_on_all_layers_selection 0x0000000_00000000)
(disableapertmacros no)
(usegerberextensions no)
(usegerberattributes yes)
(usegerberadvancedattributes yes)
(creategerberjobfile yes)
(dashed_line_dash_ratio 12.000000)
(dashed_line_gap_ratio 3.000000)
(svgprecision 4)
(plotframeref no)
(viasonmask no)
(mode 1)
(useauxorigin no)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(pdf_front_fp_property_popups yes)
(pdf_back_fp_property_popups yes)
(dxfpolygonmode yes)
(dxfimperialunits yes)
(dxfusepcbnewfont yes)
(psnegative no)
(psa4output no)
(plotreference yes)
(plotvalue yes)
(plotfptext yes)
(plotinvisibletext no)
(sketchpadsonfab no)
(subtractmaskfromsilk no)
(outputformat 1)
(mirror no)
(drillshape 1)
(scaleselection 1)
(outputdirectory "")
)
)
(net 0 "")
(gr_text "Example Tuning generator"
(at 105.13 46.81 0)
(layer "Cmts.User")
(uuid "53c1f939-ba9e-4da8-9dfc-8f32e3549f4d")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
(bold yes)
)
(justify left bottom)
)
)
(segment
(start 119.471487 50.14)
(end 119.471487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "23598711-1292-428d-920c-a74be818ad7e")
)
(segment
(start 122.471487 48.44)
(end 122.471487 49.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "32dfa4c2-9427-47a8-bd2d-ceb643557c88")
)
(segment
(start 116.471487 48.44)
(end 116.471487 49.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "44d73d7d-cf4f-4327-b231-2463bdfe4326")
)
(segment
(start 118.271487 50.14)
(end 118.271487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "48626af6-29e2-4f63-9d3e-122aa7b4ab9c")
)
(segment
(start 121.271487 50.14)
(end 121.271487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "4b411291-a17e-456b-a755-a48e9631eb4a")
)
(segment
(start 121.871487 51.84)
(end 121.871487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "4e879df0-63f3-4cb5-9164-ba33f0b14629")
)
(segment
(start 116.471487 49.84)
(end 116.471487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "588a4917-59d3-4955-9add-663bc4767847")
)
(segment
(start 117.071487 51.84)
(end 117.071487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "59b90d87-2f26-45db-9ce8-68ce8720ea38")
)
(segment
(start 123.13735 50.14)
(end 137.31 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "65de65ea-c59a-49b1-9861-84c37ec18480")
)
(segment
(start 118.271487 51.84)
(end 118.271487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "6f4c6cc9-69de-4bc5-af94-c19e9090a86d")
)
(segment
(start 121.871487 50.14)
(end 121.871487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "72c5d2fa-96ad-46fa-b509-ba435bef0d9f")
)
(segment
(start 119.471487 51.84)
(end 119.471487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "9568f820-d1e6-490c-ba36-a4f2bbd6740c")
)
(segment
(start 121.271487 48.44)
(end 121.271487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "9a9a8f38-4d0b-433a-b590-5d7512f8439b")
)
(segment
(start 120.071487 48.44)
(end 120.071487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a33210e6-9f45-4513-9f49-0851a05915d6")
)
(segment
(start 117.671487 48.44)
(end 117.671487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a4375fde-a926-4e9f-bce5-e55f71434880")
)
(segment
(start 115.871487 49.84)
(end 115.871487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a764fcd6-6263-450e-b747-c64338e0d901")
)
(segment
(start 120.671487 50.14)
(end 120.671487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a9194b6b-c1cb-4532-812c-d60b7a2c3e42")
)
(segment
(start 102.24 50.14)
(end 115.571487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "be40dcb4-4ea4-4d02-b4a7-023ff28a179f")
)
(segment
(start 118.871487 48.44)
(end 118.871487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "c05fe201-beaa-4f3d-8f86-2c044c39a7ad")
)
(segment
(start 117.671487 50.14)
(end 117.671487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "c57febd1-a087-4666-84b8-277ae6bc22d2")
)
(segment
(start 120.071487 50.14)
(end 120.071487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "dabeb0f1-d930-4995-8ecf-a4549a0b252f")
)
(segment
(start 118.871487 50.14)
(end 118.871487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "db664cf3-f269-4ad7-a42c-5f1e0f68c331")
)
(segment
(start 120.671487 51.84)
(end 120.671487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "deea7a88-92cb-4b2d-944a-56499ad070bc")
)
(segment
(start 122.771487 50.14)
(end 123.13735 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "ee8ed2c3-24bd-4b28-a241-887d40cca598")
)
(segment
(start 117.071487 50.14)
(end 117.071487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "faa07f56-f9fe-4e13-88c3-8d80b6691460")
)
(arc
(start 117.971487 52.14)
(mid 118.183619 52.052132)
(end 118.271487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "0376a7f9-ca8e-458b-9d43-8cd3a2a6bc63")
)
(arc
(start 115.571487 50.14)
(mid 115.783619 50.052132)
(end 115.871487 49.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "0461661b-2681-445d-844d-36fe87fd5675")
)
(arc
(start 120.371487 52.14)
(mid 120.583619 52.052132)
(end 120.671487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "06764c74-03e5-4cdd-9d3c-66a9449a0b79")
)
(arc
(start 119.471487 48.44)
(mid 119.559355 48.227868)
(end 119.771487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "19d41ad9-cced-4f7a-b477-770f3747302b")
)
(arc
(start 116.471487 51.84)
(mid 116.559355 52.052132)
(end 116.771487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "2f6798f2-7245-45ac-b638-798d5cc07bf0")
)
(arc
(start 122.171487 48.14)
(mid 122.383619 48.227868)
(end 122.471487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "3b913f43-9eae-4c65-9978-5b8d339e4163")
)
(arc
(start 119.771487 48.14)
(mid 119.983619 48.227868)
(end 120.071487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "3d5e09fa-3d6d-4ef1-914a-0f5c228935f9")
)
(arc
(start 116.171487 48.14)
(mid 116.383619 48.227868)
(end 116.471487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "4a64cb98-0cb5-4e84-be7d-331ff151461c")
)
(arc
(start 117.371487 48.14)
(mid 117.583619 48.227868)
(end 117.671487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "71f8bf22-de50-41c8-825f-904f110a02bf")
)
(arc
(start 120.071487 51.84)
(mid 120.159355 52.052132)
(end 120.371487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "7269ec18-3e42-46f7-847b-da594f31ad8f")
)
(arc
(start 118.271487 48.44)
(mid 118.359355 48.227868)
(end 118.571487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "767c8903-fd9f-4b6f-928b-98dd2c7597aa")
)
(arc
(start 121.871487 48.44)
(mid 121.959355 48.227868)
(end 122.171487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "7e47bebe-0dd6-4cfd-94dc-ee99962d4434")
)
(arc
(start 120.971487 48.14)
(mid 121.183619 48.227868)
(end 121.271487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "81aa3b3f-7131-448f-81ce-e2677966b704")
)
(arc
(start 118.871487 51.84)
(mid 118.959355 52.052132)
(end 119.171487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "9059e5ed-2aca-4368-82ba-41b385dc3811")
)
(arc
(start 121.271487 51.84)
(mid 121.359355 52.052132)
(end 121.571487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "91c3b598-b183-4c54-a5ba-e81d86f8b752")
)
(arc
(start 117.671487 51.84)
(mid 117.759355 52.052132)
(end 117.971487 52.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "93331fa0-f088-494f-bb3f-3176a38bbf75")
)
(arc
(start 118.571487 48.14)
(mid 118.783619 48.227868)
(end 118.871487 48.44)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "93ffb905-f4d4-4d6f-9d14-0d9786a08101")
)
(arc
(start 116.771487 52.14)
(mid 116.983619 52.052132)
(end 117.071487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "9f8c447b-e5c8-4000-a9a1-c72d9bea35fb")
)
(arc
(start 120.671487 48.44)
(mid 120.759355 48.227868)
(end 120.971487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a697b4a2-c596-4045-9f46-e645ac352ae2")
)
(arc
(start 121.571487 52.14)
(mid 121.783619 52.052132)
(end 121.871487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "a8d58e65-4b30-4eb5-84c7-aee72c58f2ec")
)
(arc
(start 115.871487 48.44)
(mid 115.959355 48.227868)
(end 116.171487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "b0d4aab8-c57b-40b9-9c8b-1f3eb20c6447")
)
(arc
(start 119.171487 52.14)
(mid 119.383619 52.052132)
(end 119.471487 51.84)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "bf81b70e-6c92-4fa5-9780-102df6c38109")
)
(arc
(start 117.071487 48.44)
(mid 117.159355 48.227868)
(end 117.371487 48.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "d6d9b09a-5a95-454c-82fb-b8e919d934e0")
)
(arc
(start 122.471487 49.84)
(mid 122.559355 50.052132)
(end 122.771487 50.14)
(width 0.2)
(layer "F.Cu")
(net 0)
(uuid "eab2f350-d181-4351-8fe1-1d59f4400931")
)
(generated
(id 4f22a815-3048-42b3-86fa-eb71720d35ae)
(type tuning_pattern)
(name "Tuning Pattern")
(layer "F.Cu")
(base_line
(pts
(xy 115.571487 50.14) (xy 123.13735 50.14)
)
)
(corner_radius_percent 100)
(end
(xy 123.13735 50.14)
)
(initial_side "left")
(last_diff_pair_gap 0.18)
(last_netname "")
(last_status "too_short")
(last_track_width 0.2)
(last_tuning "75.9800 mm (too short)")
(max_amplitude 2)
(min_spacing 0.6)
(origin
(xy 115.571487 50.14)
)
(override_custom_rules no)
(rounded yes)
(single_sided no)
(target_length 100)
(target_length_max 100.1)
(target_length_min 99.9)
(target_skew 0)
(target_skew_max 0.1)
(target_skew_min -0.1)
(tuning_mode "single")
(members 0376a7f9-ca8e-458b-9d43-8cd3a2a6bc63 0461661b-2681-445d-844d-36fe87fd5675
06764c74-03e5-4cdd-9d3c-66a9449a0b79 19d41ad9-cced-4f7a-b477-770f3747302b
23598711-1292-428d-920c-a74be818ad7e 2f6798f2-7245-45ac-b638-798d5cc07bf0
32dfa4c2-9427-47a8-bd2d-ceb643557c88 3b913f43-9eae-4c65-9978-5b8d339e4163
3d5e09fa-3d6d-4ef1-914a-0f5c228935f9 44d73d7d-cf4f-4327-b231-2463bdfe4326
48626af6-29e2-4f63-9d3e-122aa7b4ab9c 4a64cb98-0cb5-4e84-be7d-331ff151461c
4b411291-a17e-456b-a755-a48e9631eb4a 4e879df0-63f3-4cb5-9164-ba33f0b14629
588a4917-59d3-4955-9add-663bc4767847 59b90d87-2f26-45db-9ce8-68ce8720ea38
6f4c6cc9-69de-4bc5-af94-c19e9090a86d 71f8bf22-de50-41c8-825f-904f110a02bf
7269ec18-3e42-46f7-847b-da594f31ad8f 72c5d2fa-96ad-46fa-b509-ba435bef0d9f
767c8903-fd9f-4b6f-928b-98dd2c7597aa 7e47bebe-0dd6-4cfd-94dc-ee99962d4434
81aa3b3f-7131-448f-81ce-e2677966b704 9059e5ed-2aca-4368-82ba-41b385dc3811
91c3b598-b183-4c54-a5ba-e81d86f8b752 93331fa0-f088-494f-bb3f-3176a38bbf75
93ffb905-f4d4-4d6f-9d14-0d9786a08101 9568f820-d1e6-490c-ba36-a4f2bbd6740c
9a9a8f38-4d0b-433a-b590-5d7512f8439b 9f8c447b-e5c8-4000-a9a1-c72d9bea35fb
a33210e6-9f45-4513-9f49-0851a05915d6 a4375fde-a926-4e9f-bce5-e55f71434880
a697b4a2-c596-4045-9f46-e645ac352ae2 a764fcd6-6263-450e-b747-c64338e0d901
a8d58e65-4b30-4eb5-84c7-aee72c58f2ec a9194b6b-c1cb-4532-812c-d60b7a2c3e42
b0d4aab8-c57b-40b9-9c8b-1f3eb20c6447 bf81b70e-6c92-4fa5-9780-102df6c38109
c05fe201-beaa-4f3d-8f86-2c044c39a7ad c57febd1-a087-4666-84b8-277ae6bc22d2
d6d9b09a-5a95-454c-82fb-b8e919d934e0 dabeb0f1-d930-4995-8ecf-a4549a0b252f
db664cf3-f269-4ad7-a42c-5f1e0f68c331 deea7a88-92cb-4b2d-944a-56499ad070bc
eab2f350-d181-4351-8fe1-1d59f4400931 ee8ed2c3-24bd-4b28-a241-887d40cca598
faa07f56-f9fe-4e13-88c3-8d80b6691460
)
)
)

View File

@ -0,0 +1,271 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.049999999999999996,
"copper_line_width": 0.19999999999999998,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.049999999999999996,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": false,
"text_position": 0,
"units_format": 1
},
"fab_line_width": 0.09999999999999999,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.09999999999999999,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
},
"silk_line_width": 0.09999999999999999,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.09999999999999999,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"net_conflict": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.5,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.7999999999999999,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.09999999999999999,
"min_via_diameter": 0.5,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 100,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.1,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "tuning_generators_load_save.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "",
"step": "",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"legacy_lib_dir": "",
"legacy_lib_list": []
},
"sheets": [],
"text_variables": {}
}

View File

@ -121,14 +121,15 @@ BOARD_ITEM& RequireBoardItemWithTypeAndId( const BOARD& aBoard, KICAD_T aItemTyp
BOARD_ITEM* item = aBoard.GetItem( aID ); BOARD_ITEM* item = aBoard.GetItem( aID );
BOOST_REQUIRE( item ); BOOST_REQUIRE( item );
BOOST_REQUIRE( item->Type() == aItemType ); BOOST_REQUIRE_EQUAL( item->Type(), aItemType );
return *item; return *item;
} }
void LoadAndTestBoardFile( const wxString aRelativePath, bool aRoundtrip, void LoadAndTestBoardFile( const wxString aRelativePath, bool aRoundtrip,
std::function<void( BOARD& )> aBoardTestFunction ) std::function<void( BOARD& )> aBoardTestFunction,
std::optional<int> aExpectedBoardVersion )
{ {
const std::string absBoardPath = const std::string absBoardPath =
KI_TEST::GetPcbnewTestDataDir() + aRelativePath.ToStdString() + ".kicad_pcb"; KI_TEST::GetPcbnewTestDataDir() + aRelativePath.ToStdString() + ".kicad_pcb";
@ -142,6 +143,13 @@ void LoadAndTestBoardFile( const wxString aRelativePath, bool aRoundtrip,
BOOST_TEST_MESSAGE( "Testing loaded board" ); BOOST_TEST_MESSAGE( "Testing loaded board" );
aBoardTestFunction( *board1 ); aBoardTestFunction( *board1 );
// If we care about the board version, check it now - but not after a roundtrip
// (as the version will be updated to the current version)
if( aExpectedBoardVersion )
{
BOOST_CHECK_EQUAL( board1->GetFileFormatVersionAtLoad(), *aExpectedBoardVersion );
}
if( aRoundtrip ) if( aRoundtrip )
{ {
const auto savePath = std::filesystem::temp_directory_path() const auto savePath = std::filesystem::temp_directory_path()

View File

@ -25,10 +25,12 @@
#ifndef QA_PCBNEW_BOARD_TEST_UTILS__H #ifndef QA_PCBNEW_BOARD_TEST_UTILS__H
#define QA_PCBNEW_BOARD_TEST_UTILS__H #define QA_PCBNEW_BOARD_TEST_UTILS__H
#include <memory>
#include <string>
#include <mutex>
#include <map> #include <map>
#include <memory>
#include <mutex>
#include <functional>
#include <optional>
#include <string>
#include <wx/string.h> #include <wx/string.h>
@ -198,9 +200,11 @@ BOARD_ITEM& RequireBoardItemWithTypeAndId( const BOARD& aBoard, KICAD_T aItemTyp
* @param aRelativePath relative path of file to load * @param aRelativePath relative path of file to load
* @param aRoundtrip true to save, reload and re-test * @param aRoundtrip true to save, reload and re-test
* @param aBoardTestFunction the function that runs tests on the board * @param aBoardTestFunction the function that runs tests on the board
* @param aExpectedBoardVersion the expected board version, or nullopt to not check
*/ */
void LoadAndTestBoardFile( const wxString aRelativePath, bool aRoundtrip, void LoadAndTestBoardFile( const wxString aRelativePath, bool aRoundtrip,
std::function<void( BOARD& )> aBoardTestFunction ); std::function<void( BOARD& )> aBoardTestFunction,
std::optional<int> aExpectedBoardVersion = std::nullopt );
void FillZones( BOARD* m_board ); void FillZones( BOARD* m_board );

View File

@ -33,7 +33,9 @@ set( QA_PCBNEW_SRCS
# test compilation units (start test_) # test compilation units (start test_)
test_array_pad_name_provider.cpp test_array_pad_name_provider.cpp
test_board_item.cpp test_board_item.cpp
test_generator_load_save.cpp
test_graphics_import_mgr.cpp test_graphics_import_mgr.cpp
test_group_load_save.cpp
test_footprint_load_save.cpp test_footprint_load_save.cpp
test_io_mgr.cpp test_io_mgr.cpp
test_lset.cpp test_lset.cpp

View File

@ -21,8 +21,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <filesystem>
#include <board.h> #include <board.h>
#include <kiid.h> #include <kiid.h>
#include <footprint.h> #include <footprint.h>
@ -42,8 +40,9 @@ struct FOOTPRINT_LOAD_TEST_FIXTURE
struct FOOTPRINT_LOAD_TEST_CASE struct FOOTPRINT_LOAD_TEST_CASE
{ {
// Which footprint this is // Which footprint to look at in the file
KIID m_footprintUuid; KIID m_footprintUuid;
// Expected values
bool m_expectedLocked; bool m_expectedLocked;
VECTOR2I m_expectedPos; VECTOR2I m_expectedPos;
}; };

View File

@ -0,0 +1,122 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <board.h>
#include <kiid.h>
#include <pcb_generator.h>
#include <pcbnew_utils/board_file_utils.h>
#include <pcbnew_utils/board_test_utils.h>
#include <qa_utils/wx_utils/unit_test_utils.h>
#include <settings/settings_manager.h>
namespace
{
struct GENERATOR_LOAD_TEST_FIXTURE
{
GENERATOR_LOAD_TEST_FIXTURE() {}
};
struct GENERATOR_LOAD_TEST_CASE
{
// Which one to look at in the file?
KIID m_searchUuid;
// Expected values
bool m_expectedLocked;
wxString m_expectedName;
unsigned m_expectedMemberCount;
};
struct GENERATOR_LOAD_BOARD_TEST_CASE
{
// The board to load
wxString m_boardFileRelativePath;
// These tests may well test specific versions of the board file format,
// so don't let it change accidentally!
int m_expectedBoardVersion;
// List of images to check
std::vector<GENERATOR_LOAD_TEST_CASE> m_generatorCases;
};
} // namespace
BOOST_FIXTURE_TEST_CASE( GeneratorLoading, GENERATOR_LOAD_TEST_FIXTURE )
{
const std::vector<GENERATOR_LOAD_BOARD_TEST_CASE> testCases{
{
"tuning_generators_load_save",
20231231,
{
// From top to bottom in the board file
{
"4f22a815-3048-42b3-86fa-eb71720d35ae",
false,
"Tuning Pattern",
47,
},
},
},
{
// Before 20231231, 'id' was used in generator s-exprs
// and we need to continue to load it for compatibility
"tuning_generators_load_save_v20231212",
20231212,
{
// From top to bottom in the board file
{
"4f22a815-3048-42b3-86fa-eb71720d35ae",
false,
"Tuning Pattern",
47,
},
},
},
};
for( const GENERATOR_LOAD_BOARD_TEST_CASE& testCase : testCases )
{
const auto doBoardTest = [&]( const BOARD& aBoard )
{
for( const GENERATOR_LOAD_TEST_CASE& testCase : testCase.m_generatorCases )
{
BOOST_TEST_MESSAGE(
"Checking for generator with UUID: " << testCase.m_searchUuid.AsString() );
const auto& generator =
static_cast<PCB_GENERATOR&>( KI_TEST::RequireBoardItemWithTypeAndId(
aBoard, PCB_GENERATOR_T, testCase.m_searchUuid ) );
BOOST_CHECK_EQUAL( generator.IsLocked(), testCase.m_expectedLocked );
BOOST_CHECK_EQUAL( generator.GetName(), testCase.m_expectedName );
BOOST_CHECK_EQUAL( generator.GetItems().size(), testCase.m_expectedMemberCount );
}
};
KI_TEST::LoadAndTestBoardFile( testCase.m_boardFileRelativePath, true, doBoardTest,
testCase.m_expectedBoardVersion );
}
}

View File

@ -0,0 +1,134 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <board.h>
#include <kiid.h>
#include <pcb_group.h>
#include <pcbnew_utils/board_file_utils.h>
#include <pcbnew_utils/board_test_utils.h>
#include <qa_utils/wx_utils/unit_test_utils.h>
#include <settings/settings_manager.h>
namespace
{
struct GROUP_LOAD_TEST_FIXTURE
{
GROUP_LOAD_TEST_FIXTURE() {}
};
struct GROUP_LOAD_TEST_CASE
{
// Which one to look at in the file?
KIID m_searchUuid;
// Expected values
bool m_expectedLocked;
wxString m_expectedName;
unsigned m_expectedMemberCount;
};
struct GROUP_LOAD_BOARD_TEST_CASE
{
// The board to load
wxString m_boardFileRelativePath;
// These tests may well test specific versions of the board file format,
// so don't let it change accidentally!
int m_expectedBoardVersion;
// List of items to check on this board
std::vector<GROUP_LOAD_TEST_CASE> m_groupCases;
};
} // namespace
/**
* @brief This is similar to group_saveload.cpp's HealthyGroups,
* but runs the other way around: it loads a fixed board file and checks that the
* groups are loaded correctly.
*
* This makes it a good place to check parsing of the board file format, as well
* as stability of the format even if it's saved at a newer format version and re-read.
*
* But it's less good at programmatic generation of interesting groups in the first place.
*/
BOOST_FIXTURE_TEST_CASE( GroupsLoadSave, GROUP_LOAD_TEST_FIXTURE )
{
const std::vector<GROUP_LOAD_BOARD_TEST_CASE> groupTestCases{
{
"groups_load_save",
20231231,
{
// From top to bottom in the board file
{
"a78cc65c-451e-451e-9147-4460cc669685",
true,
"GroupName",
2,
},
},
},
{
// Before 20231231, 'id' was used in group s-exprs
// and we need to continue to load it for compatibility
"groups_load_save_v20231212",
20231212,
{
// From top to bottom in the board file
{
"a78cc65c-451e-451e-9147-4460cc669685",
true,
"GroupName",
2,
},
},
},
};
for( const GROUP_LOAD_BOARD_TEST_CASE& testCase : groupTestCases )
{
BOOST_TEST_MESSAGE( "Test case on file: " << testCase.m_boardFileRelativePath );
const auto doBoardTest = [&]( const BOARD& aBoard )
{
for( const GROUP_LOAD_TEST_CASE& groupTestCase : testCase.m_groupCases )
{
BOOST_TEST_MESSAGE( "Checking for group with UUID: "
<< groupTestCase.m_searchUuid.AsString()
<< " and name: " << groupTestCase.m_expectedName );
const auto& group = static_cast<PCB_GROUP&>( KI_TEST::RequireBoardItemWithTypeAndId(
aBoard, PCB_GROUP_T, groupTestCase.m_searchUuid ) );
BOOST_CHECK_EQUAL( group.IsLocked(), groupTestCase.m_expectedLocked );
BOOST_CHECK_EQUAL( group.GetName(), groupTestCase.m_expectedName );
BOOST_CHECK_EQUAL( group.GetItems().size(), groupTestCase.m_expectedMemberCount );
}
};
KI_TEST::LoadAndTestBoardFile( testCase.m_boardFileRelativePath, true, doBoardTest,
testCase.m_expectedBoardVersion );
}
}

View File

@ -21,8 +21,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <filesystem>
#include <board.h> #include <board.h>
#include <kiid.h> #include <kiid.h>
#include <pcb_reference_image.h> #include <pcb_reference_image.h>
@ -42,8 +40,9 @@ struct REFERENCE_IMAGE_LOAD_TEST_FIXTURE
struct REFERENCE_IMAGE_LOAD_TEST_CASE struct REFERENCE_IMAGE_LOAD_TEST_CASE
{ {
// Which // Which one to look at in the file
KIID m_imageUuid; KIID m_imageUuid;
// Expected values
bool m_expectedLocked; bool m_expectedLocked;
VECTOR2I m_expectedPos; VECTOR2I m_expectedPos;
double m_expectedScale; double m_expectedScale;