KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pad_custom_shape_functions.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) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <board.h>
27#include <board_item.h>
28#include <pcb_shape.h>
29#include <pad.h>
31#include <geometry/shape_rect.h>
32
33
34/*
35 * Has meaning only for free shape pads.
36 * add a free shape to the shape list.
37 * the shape is a polygon (can be with thick outline), segment, circle or arc
38 */
39
40void PAD::AddPrimitivePoly( PCB_LAYER_ID aLayer, const SHAPE_POLY_SET& aPoly, int aThickness,
41 bool aFilled )
42{
43 // If aPoly has holes, convert it to a polygon with no holes.
44 SHAPE_POLY_SET poly_no_hole;
45 poly_no_hole.Append( aPoly );
46
47 if( poly_no_hole.HasHoles() )
49
50 // There should never be multiple shapes, but if there are, we split them into
51 // primitives so that we can edit them both.
52 for( int ii = 0; ii < poly_no_hole.OutlineCount(); ++ii )
53 {
54 SHAPE_POLY_SET poly_outline( poly_no_hole.COutline( ii ) );
55 PCB_SHAPE* item = new PCB_SHAPE();
56 item->SetShape( SHAPE_T::POLY );
57 item->SetFilled( aFilled );
58 item->SetPolyShape( poly_outline );
59 item->SetStroke( STROKE_PARAMS( aThickness, LINE_STYLE::SOLID ) );
60 item->SetParent( this );
61 m_padStack.AddPrimitive( item, aLayer );
62 }
63
64 SetDirty();
65}
66
67
68void PAD::AddPrimitivePoly( PCB_LAYER_ID aLayer, const std::vector<VECTOR2I>& aPoly, int aThickness,
69 bool aFilled )
70{
71 PCB_SHAPE* item = new PCB_SHAPE( nullptr, SHAPE_T::POLY );
72 item->SetFilled( aFilled );
73 item->SetPolyPoints( aPoly );
74 item->SetStroke( STROKE_PARAMS( aThickness, LINE_STYLE::SOLID ) );
75 item->SetParent( this );
76 m_padStack.AddPrimitive( item, aLayer );
77 SetDirty();
78}
79
80
82 const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList )
83{
84 // clear old list
85 DeletePrimitivesList( aLayer );
86
87 // Import to the given shape list
88 if( aPrimitivesList.size() )
89 AppendPrimitives( aLayer, aPrimitivesList );
90
91 SetDirty();
92}
93
94
96 const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList )
97{
98 // Add duplicates of aPrimitivesList to the pad primitives list:
99 for( const std::shared_ptr<PCB_SHAPE>& prim : aPrimitivesList )
100 AddPrimitive( aLayer, new PCB_SHAPE( *prim ) );
101
102 SetDirty();
103}
104
105
106void PAD::AddPrimitive( PCB_LAYER_ID aLayer, PCB_SHAPE* aPrimitive )
107{
108 aPrimitive->SetParent( this );
109 m_padStack.AddPrimitive( aPrimitive, aLayer );
110
111 SetDirty();
112}
113
114
115// clear the basic shapes list and associated data
117{
118 if( aLayer == UNDEFINED_LAYER )
119 {
121 [&]( PCB_LAYER_ID l )
122 {
124 } );
125 }
126 else
127 {
129 }
130 SetDirty();
131}
132
133
135 int aError, ERROR_LOC aErrorLoc ) const
136{
137 SHAPE_POLY_SET polyset;
138
139 for( const std::shared_ptr<PCB_SHAPE>& primitive : m_padStack.Primitives( aLayer ) )
140 {
141 if( !primitive->IsProxyItem() )
142 primitive->TransformShapeToPolygon( polyset, UNDEFINED_LAYER, 0, aError, aErrorLoc );
143 }
144
146
147 // Merge all polygons with the initial pad anchor shape
148 if( polyset.OutlineCount() )
149 {
150 aMergedPolygon->BooleanAdd( polyset, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
152 }
153}
154
156 ERROR_LOC aErrorLoc ) const
157{
158 const BOARD* board = GetBoard();
159 int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF;
160
161 aMergedPolygon->RemoveAllContours();
162
163 // Add the anchor pad shape in aMergedPolygon, others in aux_polyset:
164 // The anchor pad is always at 0,0
165 VECTOR2I padSize = GetSize( aLayer );
166
167 switch( GetAnchorPadShape( aLayer ) )
168 {
169 case PAD_SHAPE::RECTANGLE:
170 {
171 SHAPE_RECT rect( -padSize.x / 2, -padSize.y / 2, padSize.x, padSize.y );
172 aMergedPolygon->AddOutline( rect.Outline() );
173 }
174 break;
175
176 default:
177 case PAD_SHAPE::CIRCLE:
178 TransformCircleToPolygon( *aMergedPolygon, VECTOR2I( 0, 0 ), padSize.x / 2, maxError,
179 aErrorLoc );
180 break;
181 }
182
183 addPadPrimitivesToPolygon( aLayer, aMergedPolygon, maxError, aErrorLoc );
184}
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
Definition: approximation.h:32
constexpr int ARC_HIGH_DEF
Definition: base_units.h:120
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:47
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:290
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:895
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:104
void SetFilled(bool aFlag)
Definition: eda_shape.h:108
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: eda_shape.h:294
void SetShape(SHAPE_T aShape)
Definition: eda_shape.h:131
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
Definition: eda_shape.cpp:1451
void AddPrimitive(PCB_SHAPE *aShape, PCB_LAYER_ID aLayer)
Adds a custom shape primitive to the padstack.
Definition: padstack.cpp:1288
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
Definition: padstack.cpp:870
void ClearPrimitives(PCB_LAYER_ID aLayer)
Definition: padstack.cpp:1313
std::vector< std::shared_ptr< PCB_SHAPE > > & Primitives(PCB_LAYER_ID aLayer)
Definition: padstack.cpp:1276
void MergePrimitivesAsPolygon(PCB_LAYER_ID aLayer, SHAPE_POLY_SET *aMergedPolygon, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Merge all basic shapes to a SHAPE_POLY_SET.
void AddPrimitivePoly(PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aPoly, int aThickness, bool aFilled)
Has meaning only for custom shape pads.
void SetDirty()
Definition: pad.h:431
PADSTACK m_padStack
Definition: pad.h:918
void DeletePrimitivesList(PCB_LAYER_ID aLayer=UNDEFINED_LAYER)
Clear the basic shapes list.
void AddPrimitive(PCB_LAYER_ID aLayer, PCB_SHAPE *aPrimitive)
Add item to the custom shape primitives list.
void ReplacePrimitives(PCB_LAYER_ID aLayer, const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList)
Clear the current custom shape primitives list and import a new list.
void addPadPrimitivesToPolygon(PCB_LAYER_ID aLayer, SHAPE_POLY_SET *aMergedPolygon, int aError, ERROR_LOC aErrorLoc) const
void AppendPrimitives(PCB_LAYER_ID aLayer, const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList)
Import a custom shape primitive list (composed of basic shapes) and add items to the current list.
PAD_SHAPE GetAnchorPadShape(PCB_LAYER_ID aLayer) const
Definition: pad.h:215
const VECTOR2I & GetSize(PCB_LAYER_ID aLayer) const
Definition: pad.h:266
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:90
Represent a set of closed polygons.
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
bool HasHoles() const
Return true if the polygon set has any holes.
void Fracture(POLYGON_MODE aFastMode)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset union For aFastMode meaning, see function booleanOp.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify(POLYGON_MODE aFastMode)
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMo...
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
const SHAPE_LINE_CHAIN Outline() const
Definition: shape_rect.h:212
Simple container to manage line stroke parameters.
Definition: stroke_params.h:79
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691