KiCad PCB EDA Suite
fp_shape.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) 2015 Jean-Pierre Charras, [email protected]
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright (C) 2012 Wayne Stambaugh <[email protected]>
7 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <core/wx_stl_compat.h>
28#include <bitmaps.h>
29#include <core/mirror.h>
30#include <macros.h>
31#include <math/util.h> // for KiROUND
34#include <pcb_edit_frame.h>
35#include <footprint.h>
36#include <fp_shape.h>
37#include <view/view.h>
38
39
40FP_SHAPE::FP_SHAPE( FOOTPRINT* parent, SHAPE_T aShape, KICAD_T aItemType ) :
41 PCB_SHAPE( parent, aItemType, aShape )
42{
44}
45
46
48{
49}
50
51
53{
54 FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
55
56 if( fp == NULL )
57 {
59 m_end0 = m_end;
63 return;
64 }
65
67 m_end0 = m_end - fp->GetPosition();
71
77}
78
79
81{
82 FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
83
85 m_end = m_end0;
89
90 if( fp )
91 {
97
98 m_start += fp->GetPosition();
99 m_end += fp->GetPosition();
100 m_arcCenter += fp->GetPosition();
101 m_bezierC1 += fp->GetPosition();
102 m_bezierC2 += fp->GetPosition();
103 }
104
106}
107
108
109void FP_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
110{
111 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
112 {
113 FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
114
115 if( fp )
116 aList.emplace_back( _( "Footprint" ), fp->GetReference() );
117 }
118
119 // append the features shared with the base class
120 PCB_SHAPE::GetMsgPanelInfo( aFrame, aList );
121}
122
123
124wxString FP_SHAPE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
125{
126 return wxString::Format( _( "%s on %s" ),
127 ShowShape(),
128 GetLayerName() );
129}
130
131
133{
135}
136
137
139{
140 return new FP_SHAPE( *this );
141}
142
143
145{
146 switch( m_shape )
147 {
148 case SHAPE_T::ARC:
149 return m_arcCenter0;
150
151 case SHAPE_T::CIRCLE:
152 return m_start0;
153
154 default:
156 return VECTOR2I();
157 }
158}
159
160
161void FP_SHAPE::SetCenter0( const VECTOR2I& aCenter )
162{
163 switch( m_shape )
164 {
165 case SHAPE_T::ARC:
166 m_arcCenter0 = aCenter;
167 break;
168
169 case SHAPE_T::CIRCLE:
170 m_start0 = aCenter;
171 break;
172
173 default:
175 }
176}
177
178
180{
181 // If none of the input data have changed since we loaded the arc,
182 // keep the original mid point data to minimize churn
185 return m_arcMidData_0.mid;
186
187 VECTOR2I mid0 = m_start0;
188 RotatePoint( mid0, m_arcCenter0, -GetArcAngle() / 2.0 );
189 return mid0;
190}
191
192
193void FP_SHAPE::SetArcAngleAndEnd0( const EDA_ANGLE& aAngle, bool aCheckNegativeAngle )
194{
195 EDA_ANGLE angle( aAngle );
196
198 RotatePoint( m_end0, m_arcCenter0, -angle.Normalize720() );
199
200 if( aCheckNegativeAngle && aAngle < ANGLE_0 )
201 std::swap( m_start0, m_end0 );
202}
203
204
205void FP_SHAPE::SetArcGeometry0( const VECTOR2I& aStart0, const VECTOR2I& aMid0,
206 const VECTOR2I& aEnd0 )
207{
208 m_start0 = aStart0;
209 m_end0 = aEnd0;
210 m_arcCenter0 = CalcArcCenter( aStart0, aMid0, aEnd0 );
211
214 m_arcMidData_0.mid = aMid0;
216}
217
218
219void FP_SHAPE::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
220{
221 VECTOR2I pt( 0, 0 );
222
223 switch( GetShape() )
224 {
225 case SHAPE_T::ARC:
226 case SHAPE_T::SEGMENT:
227 case SHAPE_T::RECT:
228 case SHAPE_T::CIRCLE:
229 case SHAPE_T::BEZIER:
230 // If Start0 and Start are equal (ie: Footprint Editor), then flip both sets around the
231 // centre point.
232 if( m_start == m_start0 )
233 pt = aCentre;
234
235 if( aFlipLeftRight )
236 {
237 MIRROR( m_start.x, aCentre.x );
238 MIRROR( m_end.x, aCentre.x );
239 MIRROR( m_arcCenter.x, aCentre.x );
240 MIRROR( m_bezierC1.x, aCentre.x );
241 MIRROR( m_bezierC2.x, aCentre.x );
242 MIRROR( m_start0.x, pt.x );
243 MIRROR( m_end0.x, pt.x );
244 MIRROR( m_arcCenter0.x, pt.x );
245 MIRROR( m_bezierC1_0.x, pt.x );
246 MIRROR( m_bezierC2_0.x, pt.x );
247 }
248 else
249 {
250 MIRROR( m_start.y, aCentre.y );
251 MIRROR( m_end.y, aCentre.y );
252 MIRROR( m_arcCenter.y, aCentre.y );
253 MIRROR( m_bezierC1.y, aCentre.y );
254 MIRROR( m_bezierC2.y, aCentre.y );
255 MIRROR( m_start0.y, pt.y );
256 MIRROR( m_end0.y, pt.y );
257 MIRROR( m_arcCenter0.y, pt.y );
258 MIRROR( m_bezierC1_0.y, pt.y );
259 MIRROR( m_bezierC2_0.y, pt.y );
260 }
261
262 if( GetShape() == SHAPE_T::BEZIER )
264
265 if( GetShape() == SHAPE_T::ARC )
266 {
267 std::swap( m_start, m_end );
268 std::swap( m_start0, m_end0 );
269 }
270
271 break;
272
273 case SHAPE_T::POLY:
274 // polygon corners coordinates are relative to the footprint position, orientation 0
275 m_poly.Mirror( aFlipLeftRight, !aFlipLeftRight );
276 break;
277
278 default:
280 }
281
282 SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
283}
284
285
287{
288 if( GetParent() && GetParent()->GetLayer() == B_Cu )
289 return true;
290 return false;
291}
292
293
294void FP_SHAPE::Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis )
295{
296 switch( GetShape() )
297 {
298 case SHAPE_T::ARC:
299 case SHAPE_T::SEGMENT:
300 case SHAPE_T::RECT:
301 case SHAPE_T::CIRCLE:
302 case SHAPE_T::BEZIER:
303 if( aMirrorAroundXAxis )
304 {
305 MIRROR( m_start0.y, aCentre.y );
306 MIRROR( m_end0.y, aCentre.y );
307 MIRROR( m_arcCenter0.y, aCentre.y );
308 MIRROR( m_bezierC1_0.y, aCentre.y );
309 MIRROR( m_bezierC2_0.y, aCentre.y );
310 }
311 else
312 {
313 MIRROR( m_start0.x, aCentre.x );
314 MIRROR( m_end0.x, aCentre.x );
315 MIRROR( m_arcCenter0.x, aCentre.x );
316 MIRROR( m_bezierC1_0.x, aCentre.x );
317 MIRROR( m_bezierC2_0.x, aCentre.x );
318 }
319
320 if( GetShape() == SHAPE_T::ARC )
321 {
322 std::swap( m_start, m_end );
323 std::swap( m_start0, m_end0 );
324 }
325
326 if( GetShape() == SHAPE_T::BEZIER )
328
329 break;
330
331 case SHAPE_T::POLY:
332 m_poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis, aCentre );
333 break;
334
335 default:
337 }
338
339 SetDrawCoord();
340}
341
342
343void FP_SHAPE::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
344{
345 // We should rotate the relative coordinates, but to avoid duplicate code do the base class
346 // rotation of draw coordinates, which is acceptable because in the footprint editor
347 // m_Pos0 = m_Pos
348 PCB_SHAPE::Rotate( aRotCentre, aAngle );
349
350 // and now update the relative coordinates, which are the reference in most transforms.
352}
353
354
355void FP_SHAPE::Move( const VECTOR2I& aMoveVector )
356{
357 // Move an edge of the footprint.
358 // This is a footprint shape modification.
359
360 switch( GetShape() )
361 {
362 case SHAPE_T::ARC:
363 case SHAPE_T::SEGMENT:
364 case SHAPE_T::RECT:
365 case SHAPE_T::CIRCLE:
366 case SHAPE_T::BEZIER:
367 m_start0 += aMoveVector;
368 m_end0 += aMoveVector;
369 m_arcCenter0 += aMoveVector;
370 m_bezierC1_0 += aMoveVector;
371 m_bezierC2_0 += aMoveVector;
372 break;
373
374 case SHAPE_T::POLY:
375 // polygon corners coordinates are always relative to the
376 // footprint position, orientation 0
377 m_poly.Move( VECTOR2I( aMoveVector ) );
378
379 break;
380
381 default:
383 }
384
385 SetDrawCoord();
386}
387
388
389double FP_SHAPE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
390{
391 constexpr double HIDE = std::numeric_limits<double>::max();
392
393 if( !aView )
394 return 0;
395
396 // Handle Render tab switches
397 if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
398 return HIDE;
399
400 if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
401 return HIDE;
402
403 // Other layers are shown without any conditions
404 return 0.0;
405}
406
407
409{
410 if( FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( m_parent ) )
411 return fp->GetReference();
412
413 return m_parent->m_Uuid.AsString();
414}
415
416
417static struct FP_SHAPE_DESC
418{
420 {
429
430 propMgr.AddProperty( new PROPERTY<FP_SHAPE, wxString>( _HKI( "Parent" ),
433 }
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
@ show_mod_edge
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:70
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:192
PCB_LAYER_ID m_layer
Definition: board_item.h:341
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:226
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:43
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:175
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:94
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
const KIID m_Uuid
Definition: eda_item.h:492
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:496
EDA_ANGLE GetArcAngle() const
Definition: eda_shape.cpp:585
SHAPE_T m_shape
Definition: eda_shape.h:364
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
Definition: eda_shape.cpp:405
SHAPE_T GetShape() const
Definition: eda_shape.h:113
VECTOR2I m_arcCenter
Definition: eda_shape.h:372
wxString ShowShape() const
Definition: eda_shape.cpp:57
VECTOR2I m_start
Definition: eda_shape.h:369
int GetWidth() const
Definition: eda_shape.h:109
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:75
VECTOR2I m_end
Definition: eda_shape.h:370
SHAPE_POLY_SET m_poly
Definition: eda_shape.h:379
VECTOR2I m_bezierC1
Definition: eda_shape.h:375
VECTOR2I m_bezierC2
Definition: eda_shape.h:376
EDA_ANGLE GetOrientation() const
Definition: footprint.h:191
const wxString & GetReference() const
Definition: footprint.h:519
VECTOR2I GetPosition() const override
Definition: footprint.h:188
bool IsParentFlipped() const
Definition: fp_shape.cpp:286
VECTOR2I GetArcMid0() const
Definition: fp_shape.cpp:179
VECTOR2I m_start0
Start point or circle center, relative to footprint origin, orient 0.
Definition: fp_shape.h:143
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: fp_shape.cpp:132
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: fp_shape.cpp:138
virtual void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:80
VECTOR2I GetCenter0() const
Definition: fp_shape.cpp:144
VECTOR2I m_arcCenter0
Center of arc, relative to footprint origin, orient 0.
Definition: fp_shape.h:145
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip entity relative to aCentre.
Definition: fp_shape.cpp:219
VECTOR2I m_end0
End point or circle edge, relative to footprint origin, orient 0.
Definition: fp_shape.h:144
void Mirror(const VECTOR2I &aCentre, bool aMirrorAroundXAxis) override
Mirror horizontally or vertically.
Definition: fp_shape.cpp:294
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: fp_shape.cpp:109
virtual void SetLocalCoord()
Set relative coordinates from draw coordinates.
Definition: fp_shape.cpp:52
wxString GetParentAsString() const
Definition: fp_shape.cpp:408
void SetArcAngleAndEnd0(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: fp_shape.cpp:193
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: fp_shape.cpp:124
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: fp_shape.cpp:343
ARC_MID m_arcMidData_0
Originating Arc data, orient 0.
Definition: fp_shape.h:149
void SetCenter0(const VECTOR2I &aPt)
Definition: fp_shape.cpp:161
VECTOR2I m_bezierC2_0
Bezier Control Point 2, relative to footprint origin, orient 0.
Definition: fp_shape.h:147
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: fp_shape.cpp:389
void SetArcGeometry0(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Definition: fp_shape.cpp:205
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition: fp_shape.cpp:355
VECTOR2I m_bezierC1_0
Bezier Control Point 1, relative to footprint origin, orient 0.
Definition: fp_shape.h:146
~FP_SHAPE()
Definition: fp_shape.cpp:47
FP_SHAPE(FOOTPRINT *aParent, SHAPE_T aShape=SHAPE_T::SEGMENT, KICAD_T aItemType=PCB_FP_SHAPE_T)
Definition: fp_shape.cpp:40
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:69
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:410
wxString AsString() const
Definition: kiid.cpp:257
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: pcb_shape.cpp:302
virtual void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: pcb_shape.cpp:191
PROPERTY_BASE & SetIsHiddenFromLibraryEditors(bool aIsHidden=true)
Definition: property.h:298
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:74
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:76
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both)
void Move(const VECTOR2I &aVector) override
#define _HKI(x)
#define _(s)
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:429
#define PCB_EDIT_FRAME_NAME
SHAPE_T
Definition: eda_shape.h:41
static struct FP_SHAPE_DESC _FP_SHAPE_DESC
@ LAYER_MOD_FR
show footprints on front
Definition: layer_ids.h:208
@ LAYER_MOD_BK
show footprints on back
Definition: layer_ids.h:209
@ B_Cu
Definition: layer_ids.h:95
@ F_SilkS
Definition: layer_ids.h:104
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:544
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:120
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
#define TYPE_HASH(x)
Definition: property.h:63
#define NO_SETTER(owner, type)
Definition: property.h:734
#define REGISTER_TYPE(x)
Definition: property_mgr.h:328
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
VECTOR2I end
Definition: eda_shape.h:67
VECTOR2I center
Definition: eda_shape.h:68
VECTOR2I start
Definition: eda_shape.h:66
VECTOR2I mid
Definition: eda_shape.h:65
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
Definition: trigo.cpp:458
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590