KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_export_clear_polarity.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <boost/test/unit_test.hpp>
25
26#include <wx/ffile.h>
27#include <wx/filefn.h>
28#include <wx/filename.h>
29
31
32#include <export_to_pcbnew.h>
33#include <gerber_file_image.h>
36#include <layer_ids.h>
37
38
39static VECTOR2I MillimetrePoint( double aX, double aY )
40{
41 return VECTOR2I( KiROUND( aX * 1000 ), KiROUND( aY * 1000 ) );
42}
43
44
45static std::vector<SHAPE_LINE_CHAIN> ReadPolygons( const wxString& aBoard )
46{
47 std::vector<SHAPE_LINE_CHAIN> polygons;
48 size_t pos = 0;
49
50 while( ( pos = aBoard.find( wxT( "(gr_poly" ), pos ) ) != wxString::npos )
51 {
52 size_t end = aBoard.find( wxT( "(stroke" ), pos );
53 wxString block = aBoard.Mid( pos, end - pos );
54 SHAPE_LINE_CHAIN polygon;
55 size_t xy = 0;
56
57 while( ( xy = block.find( wxT( "(xy " ), xy ) ) != wxString::npos )
58 {
59 wxString coords = block.Mid( xy + 4 );
60 double x = 0;
61 double y = 0;
62
63 coords.BeforeFirst( ' ' ).ToCDouble( &x );
64 coords.AfterFirst( ' ' ).BeforeFirst( ')' ).ToCDouble( &y );
65 polygon.Append( MillimetrePoint( x, y ) );
66 xy += 4;
67 }
68
69 polygon.SetClosed( true );
70 polygons.push_back( polygon );
71 pos = end;
72 }
73
74 return polygons;
75}
76
77
78static bool InsideAnyPolygon( const std::vector<SHAPE_LINE_CHAIN>& aPolygons, const VECTOR2I& aPoint )
79{
80 for( const SHAPE_LINE_CHAIN& polygon : aPolygons )
81 {
82 if( polygon.PointInside( aPoint ) )
83 return true;
84 }
85
86 return false;
87}
88
89
90BOOST_AUTO_TEST_SUITE( ExportToPcbnew )
91
92
93BOOST_AUTO_TEST_CASE( ClearRegionCutsCopperPlane )
94{
97 std::string fn = KI_TEST::GetTestDataRootDir() + "gerbview/clear_polarity_plane.gbr";
98
99 BOOST_REQUIRE( image->LoadGerberFile( wxString::FromUTF8( fn ) ) );
100 BOOST_REQUIRE_EQUAL( images.AddGbrImage( image, 0 ), 0 );
101
102 int layerLookUpTable[GERBER_DRAWLAYERS_COUNT];
103 std::fill( std::begin( layerLookUpTable ), std::end( layerLookUpTable ), (int) UNSELECTED_LAYER );
104 layerLookUpTable[0] = F_Cu;
105
106 wxString boardFile = wxFileName::CreateTempFileName( wxT( "clear_polarity" ) );
107 GBR_TO_PCB_EXPORTER exporter( &images, nullptr, boardFile );
108
109 BOOST_REQUIRE( exporter.ExportPcb( layerLookUpTable, 2 ) );
110
111 wxString board;
112 wxFFile file( boardFile );
113
114 BOOST_REQUIRE( file.ReadAll( &board ) );
115 file.Close();
116 wxRemoveFile( boardFile );
117 images.DeleteAllImages();
118
119 std::vector<SHAPE_LINE_CHAIN> polygons = ReadPolygons( board );
120
121 // The exported board has the Y axis pointing down.
122 BOOST_CHECK_MESSAGE( !InsideAnyPolygon( polygons, MillimetrePoint( 10, -5 ) ),
123 "the copper plane still covers the cleared channel" );
124 BOOST_CHECK( InsideAnyPolygon( polygons, MillimetrePoint( 10, -2 ) ) );
125 BOOST_CHECK( InsideAnyPolygon( polygons, MillimetrePoint( 10, -8 ) ) );
126}
127
128
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:982
A helper class to export a Gerber set of files to Pcbnew.
bool ExportPcb(const int *aLayerLookUpTable, int aCopperLayers)
Save a board from a set of Gerber images.
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
int AddGbrImage(GERBER_FILE_IMAGE *aGbrImage, int aIdx)
Add a GERBER_FILE_IMAGE* at index aIdx or at the first free location if aIdx < 0.
static GERBER_FILE_IMAGE_LIST & GetImagesList()
void DeleteAllImages()
Remove all loaded data in list, and delete all images, freeing the memory.
Hold the image data and parameters for one gerber file and layer parameters.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
@ UNSELECTED_LAYER
Definition layer_ids.h:58
@ F_Cu
Definition layer_ids.h:60
#define GERBER_DRAWLAYERS_COUNT
Number of draw layers in Gerbview.
Definition layer_ids.h:541
std::string GetTestDataRootDir()
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static bool InsideAnyPolygon(const std::vector< SHAPE_LINE_CHAIN > &aPolygons, const VECTOR2I &aPoint)
static VECTOR2I MillimetrePoint(double aX, double aY)
static std::vector< SHAPE_LINE_CHAIN > ReadPolygons(const wxString &aBoard)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
VECTOR2I end
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708