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, jean-pierre.charras@ujf-grenoble.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
7  * Copyright (C) 1992-2015 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 
40 FP_SHAPE::FP_SHAPE( FOOTPRINT* parent, SHAPE_T aShape ) :
41  PCB_SHAPE( parent, PCB_FP_SHAPE_T, aShape )
42 {
43  m_layer = F_SilkS;
44 }
45 
46 
48 {
49 }
50 
51 
53 {
54  FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
55 
56  if( fp == NULL )
57  {
58  m_start0 = m_start;
59  m_end0 = m_end;
63  return;
64  }
65 
66  m_start0 = m_start - fp->GetPosition();
67  m_end0 = m_end - fp->GetPosition();
71 
72  double angle = fp->GetOrientation();
73  RotatePoint( &m_start0.x, &m_start0.y, -angle );
74  RotatePoint( &m_end0.x, &m_end0.y, -angle );
78 }
79 
80 
82 {
83  FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
84 
85  m_start = m_start0;
86  m_end = m_end0;
90 
91  if( fp )
92  {
93  RotatePoint( &m_start.x, &m_start.y, fp->GetOrientation() );
94  RotatePoint( &m_end.x, &m_end.y, fp->GetOrientation() );
98 
99  m_start += fp->GetPosition();
100  m_end += fp->GetPosition();
101  m_arcCenter += fp->GetPosition();
102  m_bezierC1 += fp->GetPosition();
103  m_bezierC2 += fp->GetPosition();
104  }
105 
107 }
108 
109 
110 void FP_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
111 {
112  FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
113 
114  aList.emplace_back( _( "Footprint" ), fp ? fp->GetReference() : _( "<invalid>" ) );
115 
116  // append the features shared with the base class
117  PCB_SHAPE::GetMsgPanelInfo( aFrame, aList );
118 }
119 
120 
121 wxString FP_SHAPE::GetSelectMenuText( EDA_UNITS aUnits ) const
122 {
123  return wxString::Format( _( "%s on %s" ),
124  ShowShape(),
125  GetLayerName() );
126 }
127 
128 
130 {
131  return BITMAPS::show_mod_edge;
132 }
133 
134 
136 {
137  return new FP_SHAPE( *this );
138 }
139 
140 
141 wxPoint FP_SHAPE::GetCenter0() const
142 {
143  switch( m_shape )
144  {
145  case SHAPE_T::ARC:
146  return m_arcCenter0;
147 
148  case SHAPE_T::CIRCLE:
149  return m_start0;
150 
151  default:
153  return wxPoint();
154  }
155 }
156 
157 
158 void FP_SHAPE::SetCenter0( const wxPoint& aCenter )
159 {
160  switch( m_shape )
161  {
162  case SHAPE_T::ARC:
163  m_arcCenter0 = aCenter;
164  break;
165 
166  case SHAPE_T::CIRCLE:
167  m_start0 = aCenter;
168  break;
169 
170  default:
172  }
173 }
174 
175 
176 wxPoint FP_SHAPE::GetArcMid0() const
177 {
178  wxPoint mid0 = m_start0;
179  RotatePoint( &mid0, m_arcCenter0, -GetArcAngle() / 2.0 );
180  return mid0;
181 }
182 
183 
184 void FP_SHAPE::SetArcAngleAndEnd0( double aAngle, bool aCheckNegativeAngle )
185 {
186  m_end0 = m_start0;
188 
189  if( aCheckNegativeAngle && aAngle < 0 )
190  std::swap( m_start0, m_end0 );
191 }
192 
193 
194 void FP_SHAPE::SetArcGeometry0( const wxPoint& aStart0, const wxPoint& aMid0, const wxPoint& aEnd0 )
195 {
196  m_start0 = aStart0;
197  m_end0 = aEnd0;
198  m_arcCenter0 = CalcArcCenter( aStart0, aMid0, aEnd0 );
199 }
200 
201 
202 void FP_SHAPE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
203 {
204  wxPoint pt( 0, 0 );
205 
206  switch( GetShape() )
207  {
208  case SHAPE_T::ARC:
209  case SHAPE_T::SEGMENT:
210  case SHAPE_T::RECT:
211  case SHAPE_T::CIRCLE:
212  case SHAPE_T::BEZIER:
213  // If Start0 and Start are equal (ie: Footprint Editor), then flip both sets around the
214  // centre point.
215  if( m_start == m_start0 )
216  pt = aCentre;
217 
218  if( aFlipLeftRight )
219  {
220  MIRROR( m_start.x, aCentre.x );
221  MIRROR( m_end.x, aCentre.x );
222  MIRROR( m_arcCenter.x, aCentre.x );
223  MIRROR( m_bezierC1.x, aCentre.x );
224  MIRROR( m_bezierC2.x, aCentre.x );
225  MIRROR( m_start0.x, pt.x );
226  MIRROR( m_end0.x, pt.x );
227  MIRROR( m_arcCenter0.x, pt.x );
228  MIRROR( m_bezierC1_0.x, pt.x );
229  MIRROR( m_bezierC2_0.x, pt.x );
230  }
231  else
232  {
233  MIRROR( m_start.y, aCentre.y );
234  MIRROR( m_end.y, aCentre.y );
235  MIRROR( m_arcCenter.y, aCentre.y );
236  MIRROR( m_bezierC1.y, aCentre.y );
237  MIRROR( m_bezierC2.y, aCentre.y );
238  MIRROR( m_start0.y, pt.y );
239  MIRROR( m_end0.y, pt.y );
240  MIRROR( m_arcCenter0.y, pt.y );
241  MIRROR( m_bezierC1_0.y, pt.y );
242  MIRROR( m_bezierC2_0.y, pt.y );
243  }
244 
245  if( GetShape() == SHAPE_T::BEZIER )
247 
248  if( GetShape() == SHAPE_T::ARC )
249  {
250  std::swap( m_start, m_end );
251  std::swap( m_start0, m_end0 );
252  }
253 
254  break;
255 
256  case SHAPE_T::POLY:
257  // polygon corners coordinates are relative to the footprint position, orientation 0
258  m_poly.Mirror( aFlipLeftRight, !aFlipLeftRight );
259  break;
260 
261  default:
263  }
264 
265  SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
266 }
267 
269 {
270  if( GetParent() && GetParent()->GetLayer() == B_Cu )
271  return true;
272  return false;
273 }
274 
275 void FP_SHAPE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
276 {
277  // Mirror an edge of the footprint. the layer is not modified
278  // This is a footprint shape modification.
279 
280  switch( GetShape() )
281  {
282  case SHAPE_T::ARC:
283  case SHAPE_T::SEGMENT:
284  case SHAPE_T::RECT:
285  case SHAPE_T::CIRCLE:
286  case SHAPE_T::BEZIER:
287  if( aMirrorAroundXAxis )
288  {
289  MIRROR( m_start0.y, aCentre.y );
290  MIRROR( m_end0.y, aCentre.y );
291  MIRROR( m_arcCenter0.y, aCentre.y );
292  MIRROR( m_bezierC1_0.y, aCentre.y );
293  MIRROR( m_bezierC2_0.y, aCentre.y );
294  }
295  else
296  {
297  MIRROR( m_start0.x, aCentre.x );
298  MIRROR( m_end0.x, aCentre.x );
299  MIRROR( m_arcCenter0.x, aCentre.x );
300  MIRROR( m_bezierC1_0.x, aCentre.x );
301  MIRROR( m_bezierC2_0.x, aCentre.x );
302  }
303 
304  if( GetShape() == SHAPE_T::BEZIER )
306 
307  break;
308 
309  case SHAPE_T::POLY:
310  // polygon corners coordinates are always relative to the
311  // footprint position, orientation 0
312  m_poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis );
313  break;
314 
315  default:
317  }
318 
319  SetDrawCoord();
320 }
321 
322 void FP_SHAPE::Rotate( const wxPoint& aRotCentre, double aAngle )
323 {
324  // We should rotate the relative coordinates, but to avoid duplicate code do the base class
325  // rotation of draw coordinates, which is acceptable because in the footprint editor
326  // m_Pos0 = m_Pos
327  PCB_SHAPE::Rotate( aRotCentre, aAngle );
328 
329  // and now update the relative coordinates, which are the reference in most transforms.
330  SetLocalCoord();
331 }
332 
333 
334 void FP_SHAPE::Move( const wxPoint& aMoveVector )
335 {
336  // Move an edge of the footprint.
337  // This is a footprint shape modification.
338 
339  switch( GetShape() )
340  {
341  case SHAPE_T::ARC:
342  case SHAPE_T::SEGMENT:
343  case SHAPE_T::RECT:
344  case SHAPE_T::CIRCLE:
345  case SHAPE_T::BEZIER:
346  m_start0 += aMoveVector;
347  m_end0 += aMoveVector;
348  m_arcCenter0 += aMoveVector;
349  m_bezierC1_0 += aMoveVector;
350  m_bezierC2_0 += aMoveVector;
351  break;
352 
353  case SHAPE_T::POLY:
354  // polygon corners coordinates are always relative to the
355  // footprint position, orientation 0
356  m_poly.Move( VECTOR2I( aMoveVector ) );
357 
358  break;
359 
360  default:
362  }
363 
364  SetDrawCoord();
365 }
366 
367 
368 double FP_SHAPE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
369 {
370  constexpr double HIDE = std::numeric_limits<double>::max();
371 
372  if( !aView )
373  return 0;
374 
375  // Handle Render tab switches
376  if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
377  return HIDE;
378 
379  if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
380  return HIDE;
381 
382  // Other layers are shown without any conditions
383  return 0.0;
384 }
385 
386 
387 static struct FP_SHAPE_DESC
388 {
390  {
399 
400  propMgr.AddProperty( new PROPERTY<FP_SHAPE, wxString>( _HKI( "Parent" ),
402  }
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:479
SHAPE_T m_shape
Definition: eda_shape.h:296
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:65
#define TYPE_HASH(x)
Definition: property.h:59
wxPoint m_bezierC1
Definition: eda_shape.h:304
T NormalizeAngle360Max(T Angle)
Normalize angle to be >=-360.0 and <= 360.0 Angle can be equal to -360 or +360.
Definition: trigo.h:241
~FP_SHAPE()
Definition: fp_shape.cpp:47
void SetArcGeometry0(const wxPoint &aStart, const wxPoint &aMid, const wxPoint &aEnd)
Definition: fp_shape.cpp:194
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:161
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
void SetArcAngleAndEnd0(double aAngle, bool aCheckNegativeAngle=false)
Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: fp_shape.cpp:184
wxString GetParentAsString() const
Definition: fp_shape.h:148
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip entity relative to aCentre.
Definition: fp_shape.cpp:202
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: fp_shape.cpp:368
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:521
double GetOrientation() const
Definition: footprint.h:190
double GetArcAngle() const
Definition: eda_shape.cpp:495
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
show footprints on back
Definition: layer_ids.h:205
wxPoint m_arcCenter0
Center of arc, relative to footprint origin, orient 0.
Definition: fp_shape.h:165
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
The base class for create windows for drawing purpose.
wxString ShowShape() const
Definition: eda_shape.cpp:53
virtual void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate this object.
Definition: pcb_shape.cpp:109
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
#define NO_SETTER(owner, type)
Definition: property.h:621
#define REGISTER_TYPE(x)
Definition: property_mgr.h:248
wxPoint m_end
Definition: eda_shape.h:300
wxPoint m_arcCenter
Definition: eda_shape.h:302
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both)
This file contains miscellaneous commonly used macros and functions.
wxPoint m_end0
End point or circle edge, relative to footprint origin, orient 0.
Definition: fp_shape.h:164
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
wxPoint m_bezierC2
Definition: eda_shape.h:305
wxPoint GetCenter0() const
Definition: fp_shape.cpp:141
wxPoint GetArcMid0() const
Definition: fp_shape.cpp:176
FP_SHAPE(FOOTPRINT *parent, SHAPE_T aShape=SHAPE_T::SEGMENT)
Definition: fp_shape.cpp:40
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: fp_shape.cpp:135
void Move(const VECTOR2I &aVector) override
SHAPE_T
Definition: eda_shape.h:40
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
Definition: fp_shape.cpp:322
wxPoint m_bezierC2_0
Bezier Control Point 2, relative to footprint origin, orient 0.
Definition: fp_shape.h:167
SHAPE_POLY_SET m_poly
Definition: eda_shape.h:308
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:110
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
show footprints on front
Definition: layer_ids.h:204
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:120
const wxString & GetReference() const
Definition: footprint.h:463
#define _(s)
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:68
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:81
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: fp_shape.cpp:129
wxPoint m_start
Definition: eda_shape.h:299
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
EDA_UNITS
Definition: eda_units.h:38
bool IsParentFlipped() const
Definition: fp_shape.cpp:268
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_BezierPoints vertex list that approximate the Bezier curve by a list of segments.
Definition: eda_shape.cpp:363
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:32
static struct FP_SHAPE_DESC _FP_SHAPE_DESC
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
void AddProperty(PROPERTY_BASE *aProperty)
Register a property.
void Mirror(const wxPoint &aCentre, bool aMirrorAroundXAxis)
Mirror an edge of the footprint.
Definition: fp_shape.cpp:275
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:100
wxPoint GetPosition() const override
Definition: footprint.h:186
PCB_LAYER_ID m_layer
Definition: board_item.h:316
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: fp_shape.cpp:121
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:36
void SetLocalCoord()
Set relative coordinates from draw coordinates.
Definition: fp_shape.cpp:52
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:62
void Move(const wxPoint &aMoveVector) override
Move an edge of the footprint.
Definition: fp_shape.cpp:334
SHAPE_T GetShape() const
Definition: eda_shape.h:92
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
wxPoint m_start0
Start point or circle center, relative to footprint origin, orient 0.
Definition: fp_shape.h:163
int m_width
Definition: eda_shape.h:297
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:135
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:73
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:454
void SetCenter0(const wxPoint &aPt)
Definition: fp_shape.cpp:158
#define _HKI(x)
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:150
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:140
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:405
wxPoint m_bezierC1_0
Bezier Control Point 1, relative to footprint origin, orient 0.
Definition: fp_shape.h:166