Browse Source
Fix layer writing/reading for copper zones
Fix layer writing/reading for copper zones
* Always enumerate layers - never use the wildcards * Keep fills on layers the zone is actually on when loading Fixes https://gitlab.com/kicad/code/kicad/-/issues/19775pcb_db
9 changed files with 542 additions and 47 deletions
-
93pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp
-
2pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h
-
2pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp
-
24pcbnew/zone.cpp
-
7pcbnew/zone.h
-
178qa/data/pcbnew/plugins/kicad_sexpr/Issue19775_ZoneLayers/LayerEnumerate.kicad_pcb
-
178qa/data/pcbnew/plugins/kicad_sexpr/Issue19775_ZoneLayers/LayerWildcard.kicad_pcb
-
2qa/tests/pcbnew/CMakeLists.txt
-
103qa/tests/pcbnew/pcb_io/kicad_sexpr/test_kicad_sexpr.cpp
@ -0,0 +1,178 @@ |
|||
(kicad_pcb |
|||
(version 20241229) |
|||
(generator "pcbnew") |
|||
(generator_version "9.0") |
|||
(general |
|||
(thickness 1.6) |
|||
(legacy_teardrops no) |
|||
) |
|||
(paper "A4") |
|||
(layers |
|||
(0 "F.Cu" signal) |
|||
(2 "B.Cu" signal) |
|||
(9 "F.Adhes" user "F.Adhesive") |
|||
(11 "B.Adhes" user "B.Adhesive") |
|||
(13 "F.Paste" user) |
|||
(15 "B.Paste" user) |
|||
(5 "F.SilkS" user "F.Silkscreen") |
|||
(7 "B.SilkS" user "B.Silkscreen") |
|||
(1 "F.Mask" user) |
|||
(3 "B.Mask" user) |
|||
(17 "Dwgs.User" user "User.Drawings") |
|||
(19 "Cmts.User" user "User.Comments") |
|||
(21 "Eco1.User" user "User.Eco1") |
|||
(23 "Eco2.User" user "User.Eco2") |
|||
(25 "Edge.Cuts" user) |
|||
(27 "Margin" user) |
|||
(31 "F.CrtYd" user "F.Courtyard") |
|||
(29 "B.CrtYd" user "B.Courtyard") |
|||
(35 "F.Fab" user) |
|||
(33 "B.Fab" user) |
|||
(39 "User.1" user) |
|||
(41 "User.2" user) |
|||
(43 "User.3" user) |
|||
(45 "User.4" user) |
|||
(47 "User.5" user) |
|||
(49 "User.6" user) |
|||
(51 "User.7" user) |
|||
(53 "User.8" user) |
|||
(55 "User.9" user) |
|||
(57 "User.10" user) |
|||
(59 "User.11" user) |
|||
(61 "User.12" user) |
|||
(63 "User.13" user) |
|||
(65 "User.14" user) |
|||
(67 "User.15" user) |
|||
(69 "User.16" user) |
|||
(71 "User.17" user) |
|||
(73 "User.18" user) |
|||
(75 "User.19" user) |
|||
(77 "User.20" user) |
|||
(79 "User.21" user) |
|||
(81 "User.22" user) |
|||
(83 "User.23" user) |
|||
(85 "User.24" user) |
|||
(87 "User.25" user) |
|||
(89 "User.26" user) |
|||
(91 "User.27" user) |
|||
(93 "User.28" user) |
|||
(95 "User.29" user) |
|||
(97 "User.30" user) |
|||
(99 "User.31" user) |
|||
(101 "User.32" user) |
|||
(103 "User.33" user) |
|||
(105 "User.34" user) |
|||
(107 "User.35" user) |
|||
(109 "User.36" user) |
|||
(111 "User.37" user) |
|||
(113 "User.38" user) |
|||
(115 "User.39" user) |
|||
(117 "User.40" user) |
|||
(119 "User.41" user) |
|||
(121 "User.42" user) |
|||
(123 "User.43" user) |
|||
(125 "User.44" user) |
|||
(127 "User.45" user) |
|||
) |
|||
(setup |
|||
(pad_to_mask_clearance 0) |
|||
(allow_soldermask_bridges_in_footprints no) |
|||
(tenting front back) |
|||
(pcbplotparams |
|||
(layerselection 0x00000000_00000000_55555555_5755f5ff) |
|||
(plot_on_all_layers_selection 0x00000000_00000000_00000000_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) |
|||
(mode 1) |
|||
(useauxorigin no) |
|||
(hpglpennumber 1) |
|||
(hpglpenspeed 20) |
|||
(hpglpendiameter 15.000000) |
|||
(pdf_front_fp_property_popups yes) |
|||
(pdf_back_fp_property_popups yes) |
|||
(pdf_metadata yes) |
|||
(pdf_single_document no) |
|||
(dxfpolygonmode yes) |
|||
(dxfimperialunits yes) |
|||
(dxfusepcbnewfont yes) |
|||
(psnegative no) |
|||
(psa4output no) |
|||
(plot_black_and_white yes) |
|||
(plotinvisibletext no) |
|||
(sketchpadsonfab no) |
|||
(plotpadnumbers no) |
|||
(hidednponfab no) |
|||
(sketchdnponfab yes) |
|||
(crossoutdnponfab yes) |
|||
(subtractmaskfromsilk no) |
|||
(outputformat 1) |
|||
(mirror no) |
|||
(drillshape 1) |
|||
(scaleselection 1) |
|||
(outputdirectory "") |
|||
) |
|||
) |
|||
(net 0 "") |
|||
(gr_rect |
|||
(start 133 69.5) |
|||
(end 160.5 87.5) |
|||
(stroke |
|||
(width 0.05) |
|||
(type default) |
|||
) |
|||
(fill no) |
|||
(layer "Edge.Cuts") |
|||
(uuid "7c811736-20e4-430d-928a-8e244126288f") |
|||
) |
|||
(zone |
|||
(net 0) |
|||
(net_name "") |
|||
(layers "F.Cu" "B.Cu") |
|||
(uuid "8233685b-9759-4751-b126-3341098ccfbc") |
|||
(hatch edge 0.5) |
|||
(connect_pads |
|||
(clearance 0.5) |
|||
) |
|||
(min_thickness 0.25) |
|||
(filled_areas_thickness no) |
|||
(fill yes |
|||
(thermal_gap 0.5) |
|||
(thermal_bridge_width 0.5) |
|||
(island_removal_mode 1) |
|||
(island_area_min 10) |
|||
) |
|||
(polygon |
|||
(pts |
|||
(xy 134 70.5) (xy 159.5 70.5) (xy 159.5 86.5) (xy 137 86.5) |
|||
) |
|||
) |
|||
(filled_polygon |
|||
(layer "F.Cu") |
|||
(island) |
|||
(pts |
|||
(xy 159.443039 70.519685) (xy 159.488794 70.572489) (xy 159.5 70.624) (xy 159.5 86.376) (xy 159.480315 86.443039) |
|||
(xy 159.427511 86.488794) (xy 159.376 86.5) (xy 137.102911 86.5) (xy 137.035872 86.480315) (xy 136.990117 86.427511) |
|||
(xy 136.981035 86.398852) (xy 134.027535 70.646852) (xy 134.034528 70.577333) (xy 134.077995 70.522631) |
|||
(xy 134.144137 70.500112) (xy 134.149411 70.5) (xy 159.376 70.5) |
|||
) |
|||
) |
|||
(filled_polygon |
|||
(layer "B.Cu") |
|||
(island) |
|||
(pts |
|||
(xy 159.443039 70.519685) (xy 159.488794 70.572489) (xy 159.5 70.624) (xy 159.5 86.376) (xy 159.480315 86.443039) |
|||
(xy 159.427511 86.488794) (xy 159.376 86.5) (xy 137.102911 86.5) (xy 137.035872 86.480315) (xy 136.990117 86.427511) |
|||
(xy 136.981035 86.398852) (xy 134.027535 70.646852) (xy 134.034528 70.577333) (xy 134.077995 70.522631) |
|||
(xy 134.144137 70.500112) (xy 134.149411 70.5) (xy 159.376 70.5) |
|||
) |
|||
) |
|||
) |
|||
(embedded_fonts no) |
|||
) |
|||
@ -0,0 +1,178 @@ |
|||
(kicad_pcb |
|||
(version 20241229) |
|||
(generator "pcbnew") |
|||
(generator_version "9.0") |
|||
(general |
|||
(thickness 1.6) |
|||
(legacy_teardrops no) |
|||
) |
|||
(paper "A4") |
|||
(layers |
|||
(0 "F.Cu" signal) |
|||
(2 "B.Cu" signal) |
|||
(9 "F.Adhes" user "F.Adhesive") |
|||
(11 "B.Adhes" user "B.Adhesive") |
|||
(13 "F.Paste" user) |
|||
(15 "B.Paste" user) |
|||
(5 "F.SilkS" user "F.Silkscreen") |
|||
(7 "B.SilkS" user "B.Silkscreen") |
|||
(1 "F.Mask" user) |
|||
(3 "B.Mask" user) |
|||
(17 "Dwgs.User" user "User.Drawings") |
|||
(19 "Cmts.User" user "User.Comments") |
|||
(21 "Eco1.User" user "User.Eco1") |
|||
(23 "Eco2.User" user "User.Eco2") |
|||
(25 "Edge.Cuts" user) |
|||
(27 "Margin" user) |
|||
(31 "F.CrtYd" user "F.Courtyard") |
|||
(29 "B.CrtYd" user "B.Courtyard") |
|||
(35 "F.Fab" user) |
|||
(33 "B.Fab" user) |
|||
(39 "User.1" user) |
|||
(41 "User.2" user) |
|||
(43 "User.3" user) |
|||
(45 "User.4" user) |
|||
(47 "User.5" user) |
|||
(49 "User.6" user) |
|||
(51 "User.7" user) |
|||
(53 "User.8" user) |
|||
(55 "User.9" user) |
|||
(57 "User.10" user) |
|||
(59 "User.11" user) |
|||
(61 "User.12" user) |
|||
(63 "User.13" user) |
|||
(65 "User.14" user) |
|||
(67 "User.15" user) |
|||
(69 "User.16" user) |
|||
(71 "User.17" user) |
|||
(73 "User.18" user) |
|||
(75 "User.19" user) |
|||
(77 "User.20" user) |
|||
(79 "User.21" user) |
|||
(81 "User.22" user) |
|||
(83 "User.23" user) |
|||
(85 "User.24" user) |
|||
(87 "User.25" user) |
|||
(89 "User.26" user) |
|||
(91 "User.27" user) |
|||
(93 "User.28" user) |
|||
(95 "User.29" user) |
|||
(97 "User.30" user) |
|||
(99 "User.31" user) |
|||
(101 "User.32" user) |
|||
(103 "User.33" user) |
|||
(105 "User.34" user) |
|||
(107 "User.35" user) |
|||
(109 "User.36" user) |
|||
(111 "User.37" user) |
|||
(113 "User.38" user) |
|||
(115 "User.39" user) |
|||
(117 "User.40" user) |
|||
(119 "User.41" user) |
|||
(121 "User.42" user) |
|||
(123 "User.43" user) |
|||
(125 "User.44" user) |
|||
(127 "User.45" user) |
|||
) |
|||
(setup |
|||
(pad_to_mask_clearance 0) |
|||
(allow_soldermask_bridges_in_footprints no) |
|||
(tenting front back) |
|||
(pcbplotparams |
|||
(layerselection 0x00000000_00000000_55555555_5755f5ff) |
|||
(plot_on_all_layers_selection 0x00000000_00000000_00000000_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) |
|||
(mode 1) |
|||
(useauxorigin no) |
|||
(hpglpennumber 1) |
|||
(hpglpenspeed 20) |
|||
(hpglpendiameter 15.000000) |
|||
(pdf_front_fp_property_popups yes) |
|||
(pdf_back_fp_property_popups yes) |
|||
(pdf_metadata yes) |
|||
(pdf_single_document no) |
|||
(dxfpolygonmode yes) |
|||
(dxfimperialunits yes) |
|||
(dxfusepcbnewfont yes) |
|||
(psnegative no) |
|||
(psa4output no) |
|||
(plot_black_and_white yes) |
|||
(plotinvisibletext no) |
|||
(sketchpadsonfab no) |
|||
(plotpadnumbers no) |
|||
(hidednponfab no) |
|||
(sketchdnponfab yes) |
|||
(crossoutdnponfab yes) |
|||
(subtractmaskfromsilk no) |
|||
(outputformat 1) |
|||
(mirror no) |
|||
(drillshape 1) |
|||
(scaleselection 1) |
|||
(outputdirectory "") |
|||
) |
|||
) |
|||
(net 0 "") |
|||
(gr_rect |
|||
(start 133 69.5) |
|||
(end 160.5 87.5) |
|||
(stroke |
|||
(width 0.05) |
|||
(type default) |
|||
) |
|||
(fill no) |
|||
(layer "Edge.Cuts") |
|||
(uuid "7c811736-20e4-430d-928a-8e244126288f") |
|||
) |
|||
(zone |
|||
(net 0) |
|||
(net_name "") |
|||
(layers "*.Cu") |
|||
(uuid "8233685b-9759-4751-b126-3341098ccfbc") |
|||
(hatch edge 0.5) |
|||
(connect_pads |
|||
(clearance 0.5) |
|||
) |
|||
(min_thickness 0.25) |
|||
(filled_areas_thickness no) |
|||
(fill yes |
|||
(thermal_gap 0.5) |
|||
(thermal_bridge_width 0.5) |
|||
(island_removal_mode 1) |
|||
(island_area_min 10) |
|||
) |
|||
(polygon |
|||
(pts |
|||
(xy 134 70.5) (xy 159.5 70.5) (xy 159.5 86.5) (xy 137 86.5) |
|||
) |
|||
) |
|||
(filled_polygon |
|||
(layer "F.Cu") |
|||
(island) |
|||
(pts |
|||
(xy 159.443039 70.519685) (xy 159.488794 70.572489) (xy 159.5 70.624) (xy 159.5 86.376) (xy 159.480315 86.443039) |
|||
(xy 159.427511 86.488794) (xy 159.376 86.5) (xy 137.102911 86.5) (xy 137.035872 86.480315) (xy 136.990117 86.427511) |
|||
(xy 136.981035 86.398852) (xy 134.027535 70.646852) (xy 134.034528 70.577333) (xy 134.077995 70.522631) |
|||
(xy 134.144137 70.500112) (xy 134.149411 70.5) (xy 159.376 70.5) |
|||
) |
|||
) |
|||
(filled_polygon |
|||
(layer "B.Cu") |
|||
(island) |
|||
(pts |
|||
(xy 159.443039 70.519685) (xy 159.488794 70.572489) (xy 159.5 70.624) (xy 159.5 86.376) (xy 159.480315 86.443039) |
|||
(xy 159.427511 86.488794) (xy 159.376 86.5) (xy 137.102911 86.5) (xy 137.035872 86.480315) (xy 136.990117 86.427511) |
|||
(xy 136.981035 86.398852) (xy 134.027535 70.646852) (xy 134.034528 70.577333) (xy 134.077995 70.522631) |
|||
(xy 134.144137 70.500112) (xy 134.149411 70.5) (xy 159.376 70.5) |
|||
) |
|||
) |
|||
) |
|||
(embedded_fonts no) |
|||
) |
|||
@ -0,0 +1,103 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright The 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 <filesystem>
|
|||
#include <string>
|
|||
|
|||
#include <pcbnew_utils/board_test_utils.h>
|
|||
#include <pcbnew_utils/board_file_utils.h>
|
|||
#include <qa_utils/wx_utils/unit_test_utils.h>
|
|||
|
|||
#include <pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h>
|
|||
|
|||
#include <board.h>
|
|||
#include <zone.h>
|
|||
|
|||
|
|||
struct KICAD_SEXPR_FIXTURE |
|||
{ |
|||
KICAD_SEXPR_FIXTURE() {} |
|||
|
|||
PCB_IO_KICAD_SEXPR kicadPlugin; |
|||
}; |
|||
|
|||
|
|||
/**
|
|||
* Declares the struct as the Boost test fixture. |
|||
*/ |
|||
BOOST_FIXTURE_TEST_SUITE( KiCadSexprIO, KICAD_SEXPR_FIXTURE ) |
|||
|
|||
|
|||
/**
|
|||
* Compare all footprints declared in a *.lbr file with their KiCad reference footprint |
|||
*/ |
|||
BOOST_AUTO_TEST_CASE( Issue19775_ZoneLayerWildcards ) |
|||
{ |
|||
std::string dataPath = KI_TEST::GetPcbnewTestDataDir() + "plugins/kicad_sexpr/Issue19775_ZoneLayers/"; |
|||
|
|||
BOOST_TEST_CONTEXT( "Zone layers with wildcards" ) |
|||
{ |
|||
std::unique_ptr<BOARD> testBoard = std::make_unique<BOARD>(); |
|||
|
|||
kicadPlugin.LoadBoard( dataPath + "LayerWildcard.kicad_pcb", testBoard.get() ); |
|||
|
|||
// One zone in the file
|
|||
BOOST_CHECK( testBoard->Zones().size() == 1 ); |
|||
|
|||
ZONE* z = testBoard->Zones()[0]; |
|||
|
|||
// On both front and back layers, with zone fill on both
|
|||
BOOST_CHECK( z->GetLayerSet().Contains( F_Cu ) && z->GetLayerSet().Contains( B_Cu ) ); |
|||
BOOST_CHECK( z->GetFilledPolysList( F_Cu )->TotalVertices() > 0 ); |
|||
BOOST_CHECK( z->GetFilledPolysList( B_Cu )->TotalVertices() > 0 ); |
|||
} |
|||
|
|||
BOOST_TEST_CONTEXT( "Round trip layers" ) |
|||
{ |
|||
auto tmpBoard = std::filesystem::temp_directory_path() / "Issue19775_RoundTrip.kicad_pcb"; |
|||
|
|||
// Load and save the board from above to test how we write the zones into it
|
|||
{ |
|||
std::unique_ptr<BOARD> testBoard = std::make_unique<BOARD>(); |
|||
kicadPlugin.LoadBoard( dataPath + "LayerEnumerate.kicad_pcb", testBoard.get() ); |
|||
kicadPlugin.SaveBoard( tmpBoard.string(), testBoard.get() ); |
|||
} |
|||
|
|||
// Read the new board
|
|||
std::unique_ptr<BOARD> testBoard = std::make_unique<BOARD>(); |
|||
kicadPlugin.LoadBoard( tmpBoard.string(), testBoard.get() ); |
|||
|
|||
// One zone in the file
|
|||
BOOST_CHECK( testBoard->Zones().size() == 1 ); |
|||
|
|||
ZONE* z = testBoard->Zones()[0]; |
|||
|
|||
// On both front and back layers, with zone fill on both
|
|||
BOOST_CHECK( z->GetLayerSet().Contains( F_Cu ) && z->GetLayerSet().Contains( B_Cu ) ); |
|||
BOOST_CHECK( z->GetFilledPolysList( F_Cu )->TotalVertices() > 0 ); |
|||
BOOST_CHECK( z->GetFilledPolysList( B_Cu )->TotalVertices() > 0 ); |
|||
} |
|||
} |
|||
|
|||
|
|||
BOOST_AUTO_TEST_SUITE_END() |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue