KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_shape_poly_set_arcs.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 (C) 2021 Roberto Fernandez Bautista <[email protected]>
5 * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <string>
22#include <tuple>
24
27
28#include "fixtures_geometry.h"
29#include "geom_test_utils.h"
30
31
32BOOST_AUTO_TEST_SUITE( CurvedPolys )
33
34
35
39BOOST_AUTO_TEST_CASE( TestSimplify )
40{
42
43 std::map<std::string, SHAPE_POLY_SET> polysToTest =
44 {
45 { "Case 1: Single polygon", testData.holeyCurvedPolySingle },
46 { "Case 2: Wraparound polygon", testData.curvedPolyWrapRound },
47 //{ "Case 3: Multi polygon", testData.holeyCurvedPolyMulti } // This test fails right now:
48 // clipper seems to not handle
49 // multiple outlines correctly
50 };
51
52 for( std::pair<std::string, SHAPE_POLY_SET> testCase : polysToTest )
53 {
54 BOOST_TEST_CONTEXT( testCase.first )
55 {
56 SHAPE_POLY_SET testPoly = testCase.second;
57
58 double originalArea = testPoly.Area();
59
60 std::vector<SHAPE_ARC> originalArcs;
61 testPoly.GetArcs( originalArcs );
62
63 for( int i = 1; i <= 3; i++ )
64 {
65 BOOST_TEST_CONTEXT( "Simplify Iteration " << i )
66 {
68
69 std::vector<SHAPE_ARC> foundArcs;
70 testPoly.GetArcs( foundArcs );
71
72 BOOST_CHECK( GEOM_TEST::IsPolySetValid( testPoly ) );
73 BOOST_CHECK_EQUAL( testPoly.Area(), originalArea );
74 BOOST_CHECK_EQUAL( originalArcs.size(), foundArcs.size() );
75 KI_TEST::CheckUnorderedMatches( originalArcs, foundArcs,
76 []( const SHAPE_ARC& aA, const SHAPE_ARC& aB ) -> bool
77 {
78 // We accept that the arcs could be reversed after Simplify
79 return aA == aB || aA.Reversed() == aB;
80 } );
81
82 }
83 }
84 }
85 }
86}
87
88
92BOOST_AUTO_TEST_CASE( TestIntersectUnion )
93{
95
96 std::map<std::string, SHAPE_POLY_SET> polysToTest = {
97 { "Case 1: Single polygon", testData.holeyCurvedPolySingle },
98 //{ "Case 2: Multi polygon", testData.holeyCurvedPolyMulti } // This test fails right now:
99 // clipper seems to not handle
100 // multiple outlines correctly
101 };
102
103 for( std::pair<std::string, SHAPE_POLY_SET> testCase : polysToTest )
104 {
105 BOOST_TEST_CONTEXT( testCase.first )
106 {
107 SHAPE_POLY_SET testPoly = testCase.second;
108 SHAPE_POLY_SET opPoly = testData.holeyCurvedPolyInter;
109
110 // Remove all arcs before any booleanOps
111 // @todo Remove the below two lines when boolean ops can be carried out on curved polys
112 opPoly.ClearArcs();
113 testPoly.ClearArcs();
114
115 BOOST_CHECK( GEOM_TEST::IsPolySetValid( testPoly ) );
116 BOOST_CHECK( GEOM_TEST::IsPolySetValid( opPoly ) );
117
118 double testPolyArea = testPoly.Area();
119 double opPolyArea = opPoly.Area();
120
121 SHAPE_POLY_SET intersectionPoly = testPoly;
123 double intersectArea = intersectionPoly.Area();
124
125 BOOST_CHECK( GEOM_TEST::IsPolySetValid( intersectionPoly ) );
126
127
128 SHAPE_POLY_SET unionPoly = testPoly;
130 double unionArea = unionPoly.Area();
131
132 BOOST_CHECK( GEOM_TEST::IsPolySetValid( unionPoly ) );
133
134 // Acceptable error of 0.01% (fails at 0.001% for some - this is a Clipper limitation)
135 BOOST_CHECK_CLOSE( testPolyArea + opPolyArea - intersectArea, unionArea, 0.01 );
136 }
137 }
138}
139
140
144BOOST_AUTO_TEST_CASE( TestClearArcs )
145{
147
148 std::map<std::string, SHAPE_POLY_SET> polysToTest = {
149 { "Case 1: Single polygon", testData.holeyCurvedPolySingle },
150 { "Case 2: Intersect polygon", testData.holeyCurvedPolyInter },
151 { "Case 3: Multi polygon", testData.holeyCurvedPolyMulti }
152 };
153
154 for( std::pair<std::string, SHAPE_POLY_SET> testCase : polysToTest )
155 {
156 BOOST_TEST_CONTEXT( testCase.first )
157 {
158 SHAPE_POLY_SET testPoly = testCase.second;
159 double originalArea = testPoly.Area();
160 testPoly.ClearArcs();
161
162 BOOST_CHECK( GEOM_TEST::IsPolySetValid( testPoly ) );
163 BOOST_CHECK_EQUAL( testPoly.Area(), originalArea ); // Area should not have changed
164
165 std::vector<SHAPE_ARC> arcBuffer;
166 testPoly.GetArcs( arcBuffer );
167
168 BOOST_CHECK_EQUAL( arcBuffer.size(), 0 ); // All arcs should have been removed
169 }
170 }
171}
172
SHAPE_ARC Reversed() const
Definition: shape_arc.cpp:680
Represent a set of closed polygons.
void ClearArcs()
Removes all arc references from all the outlines and holes in the polyset.
double Area()
Return the area of this poly set.
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset union For aFastMode meaning, see function booleanOp.
void GetArcs(std::vector< SHAPE_ARC > &aArcBuffer) const
Appends all the arcs in this polyset to aArcBuffer.
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset intersection For aFastMode meaning, see function booleanOp.
void Simplify(POLYGON_MODE aFastMode)
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMo...
bool IsPolySetValid(const SHAPE_POLY_SET &aSet)
Verify that a SHAPE_POLY_SET has been assembled correctly by verifying each of the outlines and holes...
void CheckUnorderedMatches(const EXP_CONT &aExpected, const FOUND_CONT &aFound, MATCH_PRED aMatchPredicate)
Check that a container of "found" objects matches a container of "expected" objects.
Common data for some of the SHAPE_POLY_SET tests:
SHAPE_POLY_SET holeyCurvedPolySingle
Polygon with a single outline + multiple holes.
SHAPE_POLY_SET holeyCurvedPolyInter
Polygon with a single outlines + multiple holes.
SHAPE_POLY_SET curvedPolyWrapRound
Causes arc wraparound when reloading from Clipper see https://gitlab.com/kicad/code/kicad/-/issues/96...
SHAPE_POLY_SET holeyCurvedPolyMulti
Polygon with a multiple outlines + multiple holes.
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(TestSimplify)
Simplify the polygon a large number of times and check that the area does not change and also that th...