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( const SHAPE_POLY_SET& aPoly, int aThickness, bool aFilled )
41{
42 // If aPoly has holes, convert it to a polygon with no holes.
43 SHAPE_POLY_SET poly_no_hole;
44 poly_no_hole.Append( aPoly );
45
46 if( poly_no_hole.HasHoles() )
48
49 // There should never be multiple shapes, but if there are, we split them into
50 // primitives so that we can edit them both.
51 for( int ii = 0; ii < poly_no_hole.OutlineCount(); ++ii )
52 {
53 SHAPE_POLY_SET poly_outline( poly_no_hole.COutline( ii ) );
54 PCB_SHAPE* item = new PCB_SHAPE();
55 item->SetShape( SHAPE_T::POLY );
56 item->SetFilled( aFilled );
57 item->SetPolyShape( poly_outline );
58 item->SetStroke( STROKE_PARAMS( aThickness, LINE_STYLE::SOLID ) );
59 item->SetParent( this );
60 m_editPrimitives.emplace_back( item );
61 }
62
63 SetDirty();
64}
65
66
67void PAD::AddPrimitivePoly( const std::vector<VECTOR2I>& aPoly, int aThickness, bool aFilled )
68{
69 PCB_SHAPE* item = new PCB_SHAPE( nullptr, SHAPE_T::POLY );
70 item->SetFilled( aFilled );
71 item->SetPolyPoints( aPoly );
72 item->SetStroke( STROKE_PARAMS( aThickness, LINE_STYLE::SOLID ) );
73 item->SetParent( this );
74 m_editPrimitives.emplace_back( item );
75 SetDirty();
76}
77
78
79void PAD::ReplacePrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList )
80{
81 // clear old list
83
84 // Import to the given shape list
85 if( aPrimitivesList.size() )
86 AppendPrimitives( aPrimitivesList );
87
88 SetDirty();
89}
90
91
92void PAD::AppendPrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList )
93{
94 // Add duplicates of aPrimitivesList to the pad primitives list:
95 for( const std::shared_ptr<PCB_SHAPE>& prim : aPrimitivesList )
96 AddPrimitive( new PCB_SHAPE( *prim ) );
97
98 SetDirty();
99}
100
101
102void PAD::AddPrimitive( PCB_SHAPE* aPrimitive )
103{
104 aPrimitive->SetParent( this );
105 m_editPrimitives.emplace_back( aPrimitive );
106
107 SetDirty();
108}
109
110
111// clear the basic shapes list and associated data
113{
114 m_editPrimitives.clear();
115
116 SetDirty();
117}
118
119
120void PAD::addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError,
121 ERROR_LOC aErrorLoc ) const
122{
123 SHAPE_POLY_SET polyset;
124
125 for( const std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives )
126 {
127 if( !primitive->IsProxyItem() )
128 primitive->TransformShapeToPolygon( polyset, UNDEFINED_LAYER, 0, aError, aErrorLoc );
129 }
130
132
133 // Merge all polygons with the initial pad anchor shape
134 if( polyset.OutlineCount() )
135 {
136 aMergedPolygon->BooleanAdd( polyset, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
138 }
139}
140
141void PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon, ERROR_LOC aErrorLoc ) const
142{
143 const BOARD* board = GetBoard();
144 int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF;
145
146 aMergedPolygon->RemoveAllContours();
147
148 // Add the anchor pad shape in aMergedPolygon, others in aux_polyset:
149 // The anchor pad is always at 0,0
150 switch( GetAnchorPadShape() )
151 {
152 case PAD_SHAPE::RECTANGLE:
153 {
154 SHAPE_RECT rect( -GetSize().x / 2, -GetSize().y / 2, GetSize().x, GetSize().y );
155 aMergedPolygon->AddOutline( rect.Outline() );
156 }
157 break;
158
159 default:
160 case PAD_SHAPE::CIRCLE:
161 TransformCircleToPolygon( *aMergedPolygon, VECTOR2I( 0, 0 ), GetSize().x / 2, maxError,
162 aErrorLoc );
163 break;
164 }
165
166 addPadPrimitivesToPolygon( aMergedPolygon, maxError, aErrorLoc );
167}
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:46
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:282
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:797
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:103
void SetFilled(bool aFlag)
Definition: eda_shape.h:96
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: eda_shape.h:270
void SetShape(SHAPE_T aShape)
Definition: eda_shape.h:119
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
Definition: eda_shape.cpp:1202
void AppendPrimitives(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.
void MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Merge all basic shapes to a SHAPE_POLY_SET.
std::vector< std::shared_ptr< PCB_SHAPE > > m_editPrimitives
Definition: pad.h:772
void DeletePrimitivesList()
Clear the basic shapes list.
void SetDirty()
Definition: pad.h:366
void AddPrimitive(PCB_SHAPE *aPrimitive)
Add item to the custom shape primitives list.
void AddPrimitivePoly(const SHAPE_POLY_SET &aPoly, int aThickness, bool aFilled)
Has meaning only for custom shape pads.
void ReplacePrimitives(const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList)
Clear the current custom shape primitives list and import a new list.
void addPadPrimitivesToPolygon(SHAPE_POLY_SET *aMergedPolygon, int aError, ERROR_LOC aErrorLoc) const
const VECTOR2I & GetSize() const
Definition: pad.h:247
PAD_SHAPE GetAnchorPadShape() const
Definition: pad.h:206
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:86
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:179
Simple container to manage line stroke parameters.
Definition: stroke_params.h:81
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.
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588