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-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  if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
113  {
114  FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
115 
116  if( fp )
117  aList.emplace_back( _( "Footprint" ), fp->GetReference() );
118  }
119 
120  // append the features shared with the base class
121  PCB_SHAPE::GetMsgPanelInfo( aFrame, aList );
122 }
123 
124 
125 wxString FP_SHAPE::GetSelectMenuText( EDA_UNITS aUnits ) const
126 {
127  return wxString::Format( _( "%s on %s" ),
128  ShowShape(),
129  GetLayerName() );
130 }
131 
132 
134 {
135  return BITMAPS::show_mod_edge;
136 }
137 
138 
140 {
141  return new FP_SHAPE( *this );
142 }
143 
144 
145 wxPoint FP_SHAPE::GetCenter0() const
146 {
147  switch( m_shape )
148  {
149  case SHAPE_T::ARC:
150  return m_arcCenter0;
151 
152  case SHAPE_T::CIRCLE:
153  return m_start0;
154 
155  default:
157  return wxPoint();
158  }
159 }
160 
161 
162 void FP_SHAPE::SetCenter0( const wxPoint& aCenter )
163 {
164  switch( m_shape )
165  {
166  case SHAPE_T::ARC:
167  m_arcCenter0 = aCenter;
168  break;
169 
170  case SHAPE_T::CIRCLE:
171  m_start0 = aCenter;
172  break;
173 
174  default:
176  }
177 }
178 
179 
180 wxPoint FP_SHAPE::GetArcMid0() const
181 {
182  // If none of the input data have changed since we loaded the arc,
183  // keep the original mid point data to minimize churn
186  return m_arcMidData_0.mid;
187 
188  wxPoint mid0 = m_start0;
189  RotatePoint( &mid0, m_arcCenter0, -GetArcAngle() / 2.0 );
190  return mid0;
191 }
192 
193 
194 void FP_SHAPE::SetArcAngleAndEnd0( double aAngle, bool aCheckNegativeAngle )
195 {
196  m_end0 = m_start0;
198 
199  if( aCheckNegativeAngle && aAngle < 0 )
200  std::swap( m_start0, m_end0 );
201 }
202 
203 
204 void FP_SHAPE::SetArcGeometry0( const wxPoint& aStart0, const wxPoint& aMid0, const wxPoint& aEnd0 )
205 {
206  m_start0 = aStart0;
207  m_end0 = aEnd0;
208  m_arcCenter0 = CalcArcCenter( aStart0, aMid0, aEnd0 );
209 
212  m_arcMidData_0.mid = aMid0;
214 }
215 
216 
217 void FP_SHAPE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
218 {
219  wxPoint pt( 0, 0 );
220 
221  switch( GetShape() )
222  {
223  case SHAPE_T::ARC:
224  case SHAPE_T::SEGMENT:
225  case SHAPE_T::RECT:
226  case SHAPE_T::CIRCLE:
227  case SHAPE_T::BEZIER:
228  // If Start0 and Start are equal (ie: Footprint Editor), then flip both sets around the
229  // centre point.
230  if( m_start == m_start0 )
231  pt = aCentre;
232 
233  if( aFlipLeftRight )
234  {
235  MIRROR( m_start.x, aCentre.x );
236  MIRROR( m_end.x, aCentre.x );
237  MIRROR( m_arcCenter.x, aCentre.x );
238  MIRROR( m_bezierC1.x, aCentre.x );
239  MIRROR( m_bezierC2.x, aCentre.x );
240  MIRROR( m_start0.x, pt.x );
241  MIRROR( m_end0.x, pt.x );
242  MIRROR( m_arcCenter0.x, pt.x );
243  MIRROR( m_bezierC1_0.x, pt.x );
244  MIRROR( m_bezierC2_0.x, pt.x );
245  }
246  else
247  {
248  MIRROR( m_start.y, aCentre.y );
249  MIRROR( m_end.y, aCentre.y );
250  MIRROR( m_arcCenter.y, aCentre.y );
251  MIRROR( m_bezierC1.y, aCentre.y );
252  MIRROR( m_bezierC2.y, aCentre.y );
253  MIRROR( m_start0.y, pt.y );
254  MIRROR( m_end0.y, pt.y );
255  MIRROR( m_arcCenter0.y, pt.y );
256  MIRROR( m_bezierC1_0.y, pt.y );
257  MIRROR( m_bezierC2_0.y, pt.y );
258  }
259 
260  if( GetShape() == SHAPE_T::BEZIER )
262 
263  if( GetShape() == SHAPE_T::ARC )
264  {
265  std::swap( m_start, m_end );
266  std::swap( m_start0, m_end0 );
267  }
268 
269  break;
270 
271  case SHAPE_T::POLY:
272  // polygon corners coordinates are relative to the footprint position, orientation 0
273  m_poly.Mirror( aFlipLeftRight, !aFlipLeftRight );
274  break;
275 
276  default:
278  }
279 
280  SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
281 }
282 
284 {
285  if( GetParent() && GetParent()->GetLayer() == B_Cu )
286  return true;
287  return false;
288 }
289 
290 void FP_SHAPE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
291 {
292  // Mirror an edge of the footprint. the layer is not modified
293  // This is a footprint shape modification.
294 
295  switch( GetShape() )
296  {
297  case SHAPE_T::ARC:
298  case SHAPE_T::SEGMENT:
299  case SHAPE_T::RECT:
300  case SHAPE_T::CIRCLE:
301  case SHAPE_T::BEZIER:
302  if( aMirrorAroundXAxis )
303  {
304  MIRROR( m_start0.y, aCentre.y );
305  MIRROR( m_end0.y, aCentre.y );
306  MIRROR( m_arcCenter0.y, aCentre.y );
307  MIRROR( m_bezierC1_0.y, aCentre.y );
308  MIRROR( m_bezierC2_0.y, aCentre.y );
309  }
310  else
311  {
312  MIRROR( m_start0.x, aCentre.x );
313  MIRROR( m_end0.x, aCentre.x );
314  MIRROR( m_arcCenter0.x, aCentre.x );
315  MIRROR( m_bezierC1_0.x, aCentre.x );
316  MIRROR( m_bezierC2_0.x, aCentre.x );
317  }
318 
319  if( GetShape() == SHAPE_T::ARC )
320  {
321  std::swap( m_start, m_end );
322  std::swap( m_start0, m_end0 );
323  }
324 
325  if( GetShape() == SHAPE_T::BEZIER )
327 
328  break;
329 
330  case SHAPE_T::POLY:
331  // polygon corners coordinates are always relative to the
332  // footprint position, orientation 0
333  m_poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis );
334  break;
335 
336  default:
338  }
339 
340  SetDrawCoord();
341 }
342 
343 void FP_SHAPE::Rotate( const wxPoint& aRotCentre, double 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.
351  SetLocalCoord();
352 }
353 
354 
355 void FP_SHAPE::Move( const wxPoint& 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 
389 double 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 
408 static struct FP_SHAPE_DESC
409 {
411  {
420 
421  propMgr.AddProperty( new PROPERTY<FP_SHAPE, wxString>( _HKI( "Parent" ),
423  }
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:478
SHAPE_T m_shape
Definition: eda_shape.h:319
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:65
#define TYPE_HASH(x)
Definition: property.h:59
wxPoint m_bezierC1
Definition: eda_shape.h:328
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:204
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:164
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:194
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:217
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: fp_shape.cpp:389
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:530
double GetOrientation() const
Definition: footprint.h:191
double GetArcAngle() const
Definition: eda_shape.cpp:536
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
show footprints on back
Definition: layer_ids.h:216
ARC_MID m_arcMidData_0
Originating Arc data, orient 0.
Definition: fp_shape.h:169
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:56
virtual void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate this object.
Definition: pcb_shape.cpp:109
VECTOR2< int > VECTOR2I
Definition: vector2d.h:622
#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:323
wxPoint m_arcCenter
Definition: eda_shape.h:325
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:329
wxPoint GetCenter0() const
Definition: fp_shape.cpp:145
wxPoint GetArcMid0() const
Definition: fp_shape.cpp:180
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:139
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:343
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:332
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:215
#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:71
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:133
wxPoint m_start
Definition: eda_shape.h:322
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:283
wxPoint mid
Definition: eda_shape.h:65
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
Definition: eda_shape.cpp:366
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:290
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:99
wxPoint start
Definition: eda_shape.h:66
wxPoint GetPosition() const override
Definition: footprint.h:187
PCB_LAYER_ID m_layer
Definition: board_item.h:313
wxPoint center
Definition: eda_shape.h:68
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:125
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
wxPoint end
Definition: eda_shape.h:67
void Move(const wxPoint &aMoveVector) override
Move an edge of the footprint.
Definition: fp_shape.cpp:355
#define PCB_EDIT_FRAME_NAME
SHAPE_T GetShape() const
Definition: eda_shape.h:101
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:320
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:136
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:75
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:525
void SetCenter0(const wxPoint &aPt)
Definition: fp_shape.cpp:162
#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:143
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