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 <bitmaps.h>
28 #include <core/mirror.h>
29 #include <math/util.h> // for KiROUND
32 #include <pcb_edit_frame.h>
33 #include <board.h>
34 #include <footprint.h>
35 #include <fp_shape.h>
36 #include <view/view.h>
37 
38 
40  PCB_SHAPE( parent, PCB_FP_SHAPE_T )
41 {
42  m_shape = aShape;
43  m_angle = 0;
44  m_layer = F_SilkS;
45 }
46 
47 
49 {
50 }
51 
52 
54 {
55  FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
56 
57  if( fp == NULL )
58  {
59  m_Start0 = m_start;
60  m_End0 = m_end;
64  return;
65  }
66 
67  m_Start0 = m_start - fp->GetPosition();
68  m_End0 = m_end - fp->GetPosition();
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_thirdPoint += 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( m_shape ),
125  GetLayerName() );
126 }
127 
128 
130 {
131  return show_mod_edge_xpm;
132 }
133 
134 
136 {
137  return new FP_SHAPE( *this );
138 }
139 
140 
141 void FP_SHAPE::SetAngle( double aAngle, bool aUpdateEnd )
142 {
143  // Mark as depreciated.
144  // m_Angle does not define the arc anymore
145  // Update the parent class (updates the global m_ThirdPoint)
146  PCB_SHAPE::SetAngle( aAngle, aUpdateEnd );
147 
148  // Also update the local m_ThirdPoint0 if requested
149  if( aUpdateEnd )
150  {
153  }
154 }
155 
156 
157 void FP_SHAPE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
158 {
159  wxPoint pt( 0, 0 );
160 
161  switch( GetShape() )
162  {
163  case S_ARC:
164  // Update arc angle but do not yet update m_ThirdPoint0 and m_thirdPoint,
165  // arc center and start point must be updated before calculation arc end.
166  SetAngle( -GetAngle(), false );
168 
169  default:
170  case S_SEGMENT:
171  case S_CURVE:
172  // If Start0 and Start are equal (ie: Footprint Editor), then flip both sets around the
173  // centre point.
174  if( m_start == m_Start0 )
175  pt = aCentre;
176 
177  if( aFlipLeftRight )
178  {
179  MIRROR( m_start.x, aCentre.x );
180  MIRROR( m_end.x, aCentre.x );
181  MIRROR( m_thirdPoint.x, aCentre.x );
182  MIRROR( m_bezierC1.x, aCentre.x );
183  MIRROR( m_bezierC2.x, aCentre.x );
184  MIRROR( m_Start0.x, pt.x );
185  MIRROR( m_End0.x, pt.x );
186  MIRROR( m_ThirdPoint0.x, pt.x );
187  MIRROR( m_Bezier0_C1.x, pt.x );
188  MIRROR( m_Bezier0_C2.x, pt.x );
189  }
190  else
191  {
192  MIRROR( m_start.y, aCentre.y );
193  MIRROR( m_end.y, aCentre.y );
194  MIRROR( m_thirdPoint.y, aCentre.y );
195  MIRROR( m_bezierC1.y, aCentre.y );
196  MIRROR( m_bezierC2.y, aCentre.y );
197  MIRROR( m_Start0.y, pt.y );
198  MIRROR( m_End0.y, pt.y );
199  MIRROR( m_ThirdPoint0.y, pt.y );
200  MIRROR( m_Bezier0_C1.y, pt.y );
201  MIRROR( m_Bezier0_C2.y, pt.y );
202  }
203 
205  break;
206 
207  case S_POLYGON:
208  // polygon corners coordinates are relative to the footprint position, orientation 0
209  m_poly.Mirror( aFlipLeftRight, !aFlipLeftRight );
210  break;
211  }
212 
213  SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
214 }
215 
217 {
218  if( GetParent() && GetParent()->GetLayer() == B_Cu )
219  return true;
220  return false;
221 }
222 
223 void FP_SHAPE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
224 {
225  // Mirror an edge of the footprint. the layer is not modified
226  // This is a footprint shape modification.
227 
228  switch( GetShape() )
229  {
230  case S_ARC:
231  // Update arc angle but do not yet update m_ThirdPoint0 and m_thirdPoint,
232  // arc center and start point must be updated before calculation arc end.
233  SetAngle( -GetAngle(), false );
235 
236  default:
237  case S_CURVE:
238  case S_SEGMENT:
239  if( aMirrorAroundXAxis )
240  {
241  MIRROR( m_Start0.y, aCentre.y );
242  MIRROR( m_End0.y, aCentre.y );
243  MIRROR( m_ThirdPoint0.y, aCentre.y );
244  MIRROR( m_Bezier0_C1.y, aCentre.y );
245  MIRROR( m_Bezier0_C2.y, aCentre.y );
246  }
247  else
248  {
249  MIRROR( m_Start0.x, aCentre.x );
250  MIRROR( m_End0.x, aCentre.x );
251  MIRROR( m_ThirdPoint0.x, aCentre.x );
252  MIRROR( m_Bezier0_C1.x, aCentre.x );
253  MIRROR( m_Bezier0_C2.x, aCentre.x );
254  }
255 
256  for( unsigned ii = 0; ii < m_bezierPoints.size(); ii++ )
257  {
258  if( aMirrorAroundXAxis )
259  MIRROR( m_bezierPoints[ii].y, aCentre.y );
260  else
261  MIRROR( m_bezierPoints[ii].x, aCentre.x );
262  }
263 
264  break;
265 
266  case S_POLYGON:
267  // polygon corners coordinates are always relative to the
268  // footprint position, orientation 0
269  m_poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis );
270  break;
271  }
272 
273  SetDrawCoord();
274 }
275 
276 void FP_SHAPE::Rotate( const wxPoint& aRotCentre, double aAngle )
277 {
278  // We should rotate the relative coordinates, but to avoid duplicate code do the base class
279  // rotation of draw coordinates, which is acceptable because in the footprint editor
280  // m_Pos0 = m_Pos
281  PCB_SHAPE::Rotate( aRotCentre, aAngle );
282 
283  // and now update the relative coordinates, which are the reference in most transforms.
284  SetLocalCoord();
285 }
286 
287 
288 void FP_SHAPE::Move( const wxPoint& aMoveVector )
289 {
290  // Move an edge of the footprint.
291  // This is a footprint shape modification.
292  m_Start0 += aMoveVector;
293  m_End0 += aMoveVector;
294  m_ThirdPoint0 += aMoveVector;
295  m_Bezier0_C1 += aMoveVector;
296  m_Bezier0_C2 += aMoveVector;
297 
298  switch( GetShape() )
299  {
300  default:
301  break;
302 
303  case S_POLYGON:
304  // polygon corners coordinates are always relative to the
305  // footprint position, orientation 0
306  m_poly.Move( VECTOR2I( aMoveVector ) );
307 
308  break;
309  }
310 
311  SetDrawCoord();
312 }
313 
314 
315 double FP_SHAPE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
316 {
317  constexpr double HIDE = std::numeric_limits<double>::max();
318 
319  if( !aView )
320  return 0;
321 
322  // Handle Render tab switches
323  if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
324  return HIDE;
325 
326  if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
327  return HIDE;
328 
329  // Other layers are shown without any conditions
330  return 0.0;
331 }
332 
333 
334 static struct FP_SHAPE_DESC
335 {
337  {
341 
342  propMgr.AddProperty( new PROPERTY<FP_SHAPE, wxString>( _HKI( "Parent" ),
344  }
FP_SHAPE(FOOTPRINT *parent, PCB_SHAPE_TYPE_T aShape=S_SEGMENT)
Definition: fp_shape.cpp:39
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:528
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:66
#define TYPE_HASH(x)
Definition: property.h:57
wxPoint m_end
Definition: pcb_shape.h:49
PNG memory record (file in memory).
Definition: bitmap_def.h:29
~FP_SHAPE()
Definition: fp_shape.cpp:48
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:194
PCB_SHAPE_TYPE_T m_shape
Definition: pcb_shape.h:52
wxString GetParentAsString() const
Definition: fp_shape.h:146
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip entity relative to aCentre.
Definition: fp_shape.cpp:157
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: fp_shape.cpp:315
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:521
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:54
show footprints on back
double GetOrientation() const
Definition: footprint.h:186
static wxString ShowShape(PCB_SHAPE_TYPE_T aShape)
Convert the enum PCB_SHAPE_TYPE_T integer value to a wxString.
Definition: board_item.cpp:31
usual segment : line with rounded ends
Definition: board_item.h:50
Arcs (with rounded ends)
Definition: board_item.h:52
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
The base class for create windows for drawing purpose.
virtual void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate this object.
Definition: pcb_shape.cpp:197
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
#define NO_SETTER(owner, type)
Definition: property.h:605
#define REGISTER_TYPE(x)
Definition: property_mgr.h:249
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirror the line points about y or x (or both)
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
wxPoint m_thirdPoint
Definition: pcb_shape.h:50
show footprints on front
wxPoint m_ThirdPoint0
End point for an arc.
Definition: fp_shape.h:162
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: fp_shape.cpp:135
PCB_SHAPE_TYPE_T
The set of shapes for PCB graphics and tracks and footprint graphics in the .m_Shape member.
Definition: board_item.h:48
#define NULL
void Move(const VECTOR2I &aVector) override
SHAPE_POLY_SET m_poly
Definition: pcb_shape.h:58
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
Definition: fp_shape.cpp:276
void SetAngle(double aAngle, bool aUpdateEnd=true) override
Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: fp_shape.cpp:141
virtual BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:46
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
wxPoint m_End0
End point, relative to footprint origin, orient 0.
Definition: fp_shape.h:161
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
wxPoint m_Start0
Start point or center, relative to footprint origin, orient 0.
Definition: fp_shape.h:160
const wxString & GetReference() const
Definition: footprint.h:423
double m_angle
Definition: pcb_shape.h:53
BITMAP_DEF GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: fp_shape.cpp:129
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:81
wxPoint m_Bezier0_C2
Bezier Control Point 2, relative to footprint origin, orient 0.
Definition: fp_shape.h:164
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
wxPoint m_start
Definition: pcb_shape.h:48
EDA_UNITS
Definition: eda_units.h:38
bool IsParentFlipped() const
Definition: fp_shape.cpp:216
const BITMAP_OPAQUE show_mod_edge_xpm[1]
int m_width
Definition: pcb_shape.h:46
#define _(s)
Definition: 3d_actions.cpp:33
static struct FP_SHAPE_DESC _FP_SHAPE_DESC
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
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:223
double GetAngle() const
Definition: pcb_shape.h:127
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:149
wxPoint GetPosition() const override
Definition: footprint.h:182
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_BezierPoints vertex list that approximate the Bezier curve by a list of segments Has me...
Definition: pcb_shape.cpp:315
PCB_LAYER_ID m_layer
Definition: board_item.h:363
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
wxPoint m_bezierC1
Definition: pcb_shape.h:54
void SetLocalCoord()
Set relative coordinates from draw coordinates.
Definition: fp_shape.cpp:53
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:63
void Move(const wxPoint &aMoveVector) override
Move an edge of the footprint.
Definition: fp_shape.cpp:288
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:130
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
wxPoint m_Bezier0_C1
Bezier Control Point 1, relative to footprint origin, orient 0.
Definition: fp_shape.h:163
std::vector< wxPoint > m_bezierPoints
Definition: pcb_shape.h:57
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
virtual void SetAngle(double aAngle, bool aUpdateEnd=true)
Sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: pcb_shape.cpp:465
wxPoint m_bezierC2
Definition: pcb_shape.h:55
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:60
Bezier Curve.
Definition: board_item.h:55
#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:487
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:404