Pcbnew IO: Use fill yes/no universally

There was a motion towards fill solid/none around
2020 (c.f. b31e97cfeda9b76a165854b98974d253e221e93b),
but it was only for PCB_SHAPE.

Use yes/no universally (solid/none parsing the same way
as currently). In future if there are other fill modes
for these shapes, they can use the same pattern as ZONEs
do now: (fill yes) (hatch etc ....) or similar.

Relates-To: https://gitlab.com/kicad/code/kicad/-/issues/15232
This commit is contained in:
John Beard 2024-11-29 05:43:40 +08:00
parent ab11317d7b
commit 44ca798925
6 changed files with 543 additions and 2 deletions

View File

@ -1014,7 +1014,7 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_SHAPE* aShape ) const
|| ( aShape->GetShape() == SHAPE_T::RECTANGLE ) || ( aShape->GetShape() == SHAPE_T::RECTANGLE )
|| ( aShape->GetShape() == SHAPE_T::CIRCLE ) ) || ( aShape->GetShape() == SHAPE_T::CIRCLE ) )
{ {
m_out->Print( aShape->IsFilled() ? "(fill solid)" : "(fill none)" ); KICAD_FORMAT::FormatBool( m_out, "fill", aShape->IsFilled() );
} }
if( aShape->IsLocked() ) if( aShape->IsLocked() )

View File

@ -170,7 +170,7 @@ class PCB_IO_KICAD_SEXPR; // forward decl
//#define SEXPR_BOARD_FILE_VERSION 20241009 // Evolve placement rule areas file format //#define SEXPR_BOARD_FILE_VERSION 20241009 // Evolve placement rule areas file format
//#define SEXPR_BOARD_FILE_VERSION 20241010 // Graphic shapes can have soldermask layer and margin //#define SEXPR_BOARD_FILE_VERSION 20241010 // Graphic shapes can have soldermask layer and margin
//#define SEXPR_BOARD_FILE_VERSION 20241030 // Dimension arrow directions, suppress_zeroes normalization //#define SEXPR_BOARD_FILE_VERSION 20241030 // Dimension arrow directions, suppress_zeroes normalization
#define SEXPR_BOARD_FILE_VERSION 20241129 // Normalise keep_text_aligned properties #define SEXPR_BOARD_FILE_VERSION 20241129 // Normalise keep_text_aligned and fill properties
#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

View File

@ -0,0 +1,155 @@
(kicad_pcb
(version 20240108)
(generator "pcbnew")
(generator_version "8.0")
(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_poly
(pts
(xy 145 85) (xy 160 85) (xy 160 100) (xy 145 100)
)
(stroke
(width 0.2)
(type solid)
)
(fill solid)
(layer "F.Cu")
(uuid "65596b4f-7b03-48e9-8be7-5824316ea7fd")
)
(gr_poly
(pts
(xy 125 85) (xy 135 85) (xy 135 95) (xy 125 95)
)
(stroke
(width 0.2)
(type solid)
)
(fill none)
(layer "F.Cu")
(uuid "cf265305-49c9-43d8-bb2a-ad34997b22d6")
)
(gr_rect
(start 145 65)
(end 160 80)
(stroke
(width 0.2)
(type solid)
)
(fill solid)
(layer "F.Cu")
(uuid "d0669ae2-442f-427f-af0f-bc3008af779a")
)
(gr_rect
(start 125 65)
(end 135 75)
(stroke
(width 0.2)
(type default)
)
(fill none)
(layer "F.Cu")
(uuid "fd1649a3-9a92-4dd3-96b4-88469cb257ba")
)
(gr_text "Fill"
(at 150 60 0)
(layer "Cmts.User")
(uuid "435629a4-8d9c-4e90-ada3-ce9fb5233170")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
(bold yes)
)
(justify bottom)
)
)
(gr_text "No fill"
(at 130 60 0)
(layer "Cmts.User")
(uuid "ef55c2a1-fcfc-4a00-81d3-37a24bf772bc")
(effects
(font
(size 1.5 1.5)
(thickness 0.3)
(bold yes)
)
(justify bottom)
)
)
)

View File

@ -0,0 +1,273 @@
{
"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.05,
"copper_line_width": 0.2,
"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.05,
"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.1,
"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.1,
"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.1,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.1,
"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_symbol_mismatch": "warning",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"holes_co_located": "warning",
"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.2,
"min_microvia_drill": 0.1,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.8,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.1,
"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": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 1.0
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"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": "graphics_load_save_v20240108.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

@ -34,6 +34,7 @@ set( QA_PCBNEW_SRCS
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_generator_load_save.cpp
test_graphics_load_save.cpp
test_graphics_import_mgr.cpp test_graphics_import_mgr.cpp
test_group_load_save.cpp test_group_load_save.cpp
test_footprint_load_save.cpp test_footprint_load_save.cpp

View File

@ -0,0 +1,112 @@
/*
* 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_shape.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 GRAPHICS_LOAD_TEST_CASE
{
// Which one to look at in the file?
KIID m_searchUuid;
// Expected values
bool m_expectedFilled;
};
struct GRAPHICS_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<GRAPHICS_LOAD_TEST_CASE> m_generatorCases;
};
} // namespace
BOOST_AUTO_TEST_CASE( GraphicsLoad )
{
const std::vector<GRAPHICS_LOAD_BOARD_TEST_CASE> testCases{
{
// Before 20241129, 'fill' would be solid or none
// in PCB shapes
"graphics_load_save_v20240108",
20240108,
{
// Filled poly
{
"65596b4f-7b03-48e9-8be7-5824316ea7fd",
true,
},
// Unfilled poly
{
"cf265305-49c9-43d8-bb2a-ad34997b22d6",
false,
},
// Filled rect
{
"d0669ae2-442f-427f-af0f-bc3008af779a",
true,
},
// Unfilled rect
{
"fd1649a3-9a92-4dd3-96b4-88469cb257ba",
false,
},
},
},
};
for( const GRAPHICS_LOAD_BOARD_TEST_CASE& testCase : testCases )
{
const auto doBoardTest = [&]( const BOARD& aBoard )
{
for( const GRAPHICS_LOAD_TEST_CASE& testCase : testCase.m_generatorCases )
{
BOOST_TEST_MESSAGE(
"Checking for graphic with UUID: " << testCase.m_searchUuid.AsString() );
const auto& graphic =
static_cast<PCB_SHAPE&>( KI_TEST::RequireBoardItemWithTypeAndId(
aBoard, PCB_SHAPE_T, testCase.m_searchUuid ) );
BOOST_CHECK_EQUAL( graphic.IsFilled(), testCase.m_expectedFilled );
}
};
KI_TEST::LoadAndTestBoardFile( testCase.m_boardFileRelativePath, true, doBoardTest,
testCase.m_expectedBoardVersion );
}
}