KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_aperture_macro.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, see <https://www.gnu.org/licenses/>.
18 */
19
23
24#include <boost/test/unit_test.hpp>
25
26#include <aperture_macro.h>
27#include <am_primitive.h>
28#include <am_param.h>
29#include <dcode.h>
30#include <gerber_draw_item.h>
31#include <gerber_file_image.h>
34
35
36BOOST_AUTO_TEST_SUITE( GerbviewApertureMacro )
37
38
39namespace
40{
41
47int circlePrimitiveSegmentCount( double aDiameterMm )
48{
49 APERTURE_MACRO macro;
50 AM_PRIMITIVE prim( true, AMP_CIRCLE );
51
52 auto pushValue =
53 []( AM_PRIMITIVE& aPrim, double aValue )
54 {
55 AM_PARAM param;
56 param.PushOperator( PUSHVALUE, aValue );
57 aPrim.m_Params.push_back( param );
58 };
59
60 // exposure ON, diameter, center x, center y
61 pushValue( prim, 1.0 );
62 pushValue( prim, aDiameterMm );
63 pushValue( prim, 0.0 );
64 pushValue( prim, 0.0 );
65
66 SHAPE_POLY_SET buffer;
67 prim.ConvertBasicShapeToPolygon( &macro, buffer );
68
69 BOOST_REQUIRE_GT( buffer.OutlineCount(), 0 );
70
71 // The conversion closes the outline by repeating the first point.
72 return buffer.Outline( 0 ).PointCount() - 1;
73}
74
75} // namespace
76
77
78// Guards against regressing to a fixed segment count independent of the circle size.
79BOOST_AUTO_TEST_CASE( CirclePrimitiveTessellationScalesWithSize )
80{
81 int smallCount = circlePrimitiveSegmentCount( 0.2 );
82 int largeCount = circlePrimitiveSegmentCount( 20.0 );
83
84 // A larger circle needs more segments to hold the same maximum deviation.
85 BOOST_CHECK_GT( largeCount, smallCount );
86
87 // Both counts follow the TransformCircleToPolygon convention of a multiple of 8 segments
88 // with an 8-segment floor.
89 BOOST_CHECK_GE( smallCount, 8 );
90 BOOST_CHECK_EQUAL( smallCount % 8, 0 );
91 BOOST_CHECK_EQUAL( largeCount % 8, 0 );
92}
93
94
106BOOST_AUTO_TEST_CASE( EmptyMacroProducesNoOutlines )
107{
109
110 D_CODE* dcode = image.GetDCODEOrCreate( 10, true );
111 BOOST_REQUIRE( dcode != nullptr );
112 dcode->m_ApertType = APT_MACRO;
113
114 // A macro with no primitives simulates a macro with invalid template parameters:
115 // it produces no shapes, so GetApertureMacroShape returns an empty SHAPE_POLY_SET.
116 APERTURE_MACRO emptyMacro;
117 emptyMacro.m_AmName = wxT( "EMPTY_TEST_MACRO" );
118 dcode->SetMacro( &emptyMacro );
119
120 GERBER_DRAW_ITEM item( &image );
122 item.m_DCode = 10;
123
124 SHAPE_POLY_SET* shape = emptyMacro.GetApertureMacroShape( &item, VECTOR2I( 0, 0 ) );
125
126 BOOST_REQUIRE( shape != nullptr );
127 BOOST_CHECK_EQUAL( shape->OutlineCount(), 0 );
128
129 // ConvertShapeToPolygon must also leave m_Polygon with 0 outlines for an empty macro.
130 dcode->ConvertShapeToPolygon( &item );
132}
133
134
135BOOST_AUTO_TEST_CASE( TruncatedPrimitivesAreNotStored )
136{
137 wxString path = KI_TEST::GetTestDataRootDir() + "gerbview/aperture_macro_truncated.gbr";
139
140 BOOST_REQUIRE( image.LoadGerberFile( path ) );
141 BOOST_CHECK_EQUAL( image.GetMessages().GetCount(), 2u );
142
143 for( const char* name : { "BrokenCircle", "BrokenOutline" } )
144 {
146 {
147 APERTURE_MACRO lookup;
148 lookup.m_AmName = name;
149 BOOST_CHECK( image.FindApertureMacro( lookup ) == nullptr );
150 }
151 }
152
153 // Parsing recovers after the malformed definitions and retains valid geometry.
154 BOOST_REQUIRE_EQUAL( image.GetItems().size(), 2u );
155
156 for( GERBER_DRAW_ITEM* item : image.GetItems() )
157 {
158 D_CODE* dcode = image.GetDCODE( item->m_DCode );
159 BOOST_REQUIRE( dcode != nullptr );
160 BOOST_REQUIRE_EQUAL( dcode->m_ApertType, APT_MACRO );
161 dcode->ConvertShapeToPolygon( item );
162 BOOST_CHECK_GT( dcode->m_Polygon.OutlineCount(), 0 );
163 }
164}
165
166
const char * name
@ PUSHVALUE
Definition am_param.h:146
@ AMP_CIRCLE
Hold a parameter value for an "aperture macro" as defined within standard RS274X.
Definition am_param.h:281
void PushOperator(parm_item_type aType, double aValue)
Add an operator/operand to the current stack.
Definition am_param.cpp:123
An aperture macro primitive as given in gerber layer format doc.
AM_PARAMS m_Params
A sequence of parameters used by the primitive.
Support the "aperture macro" defined within standard RS274X.
wxString m_AmName
The name of the aperture macro as defined like AMVB_RECTANGLE* (name is VB_RECTANGLE)
SHAPE_POLY_SET * GetApertureMacroShape(const GERBER_DRAW_ITEM *aParent, const VECTOR2I &aShapePos)
Calculate the primitive shape for flashed items.
A gerber DCODE (also called Aperture) definition.
Definition dcode.h:76
void SetMacro(APERTURE_MACRO *aMacro)
Definition dcode.h:127
APERTURE_T m_ApertType
Aperture type ( Line, rectangle, circle, oval poly, macro )
Definition dcode.h:198
SHAPE_POLY_SET m_Polygon
Definition dcode.h:213
void ConvertShapeToPolygon(const GERBER_DRAW_ITEM *aParent)
Convert a shape to an equivalent polygon.
Definition dcode.cpp:288
GBR_BASIC_SHAPE_TYPE m_ShapeType
Hold the image data and parameters for one gerber file and layer parameters.
int PointCount() const
Return the number of points (vertices) in this line chain.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
@ APT_MACRO
Definition dcode.h:50
@ GBR_SPOT_MACRO
std::string GetTestDataRootDir()
BOOST_AUTO_TEST_CASE(CirclePrimitiveTessellationScalesWithSize)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string path
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708