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  // m_Angle must be >= -360 and <= +360 degrees
146  m_angle = NormalizeAngle360Max( aAngle );
147 
148  if( aUpdateEnd )
149  {
152  }
153 }
154 
155 
156 void FP_SHAPE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
157 {
158  wxPoint pt( 0, 0 );
159 
160  switch( GetShape() )
161  {
162  case S_ARC:
163  SetAngle( -GetAngle() );
165 
166  default:
167  case S_SEGMENT:
168  case S_CURVE:
169  // If Start0 and Start are equal (ie: Footprint Editor), then flip both sets around the
170  // centre point.
171  if( m_start == m_Start0 )
172  pt = aCentre;
173 
174  if( aFlipLeftRight )
175  {
176  MIRROR( m_start.x, aCentre.x );
177  MIRROR( m_end.x, aCentre.x );
178  MIRROR( m_thirdPoint.x, aCentre.x );
179  MIRROR( m_bezierC1.x, aCentre.x );
180  MIRROR( m_bezierC2.x, aCentre.x );
181  MIRROR( m_Start0.x, pt.x );
182  MIRROR( m_End0.x, pt.x );
183  MIRROR( m_ThirdPoint0.x, pt.x );
184  MIRROR( m_Bezier0_C1.x, pt.x );
185  MIRROR( m_Bezier0_C2.x, pt.x );
186  }
187  else
188  {
189  MIRROR( m_start.y, aCentre.y );
190  MIRROR( m_end.y, aCentre.y );
191  MIRROR( m_thirdPoint.y, aCentre.y );
192  MIRROR( m_bezierC1.y, aCentre.y );
193  MIRROR( m_bezierC2.y, aCentre.y );
194  MIRROR( m_Start0.y, pt.y );
195  MIRROR( m_End0.y, pt.y );
196  MIRROR( m_ThirdPoint0.y, pt.y );
197  MIRROR( m_Bezier0_C1.y, pt.y );
198  MIRROR( m_Bezier0_C2.y, pt.y );
199  }
200 
202  break;
203 
204  case S_POLYGON:
205  // polygon corners coordinates are relative to the footprint position, orientation 0
206  m_poly.Mirror( aFlipLeftRight, !aFlipLeftRight );
207  break;
208  }
209 
210  // PCB_SHAPE items are not usually on copper layers, but it can happen in microwave apps.
211  // However, currently, only on Front or Back layers.
212  // So the copper layers count is not taken in account
213  SetLayer( FlipLayer( GetLayer() ) );
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  switch( GetShape() )
228  {
229  case S_ARC:
230  SetAngle( -GetAngle() );
232 
233  default:
234  case S_CURVE:
235  case S_SEGMENT:
236  if( aMirrorAroundXAxis )
237  {
238  MIRROR( m_Start0.y, aCentre.y );
239  MIRROR( m_End0.y, aCentre.y );
240  MIRROR( m_Bezier0_C1.y, aCentre.y );
241  MIRROR( m_Bezier0_C2.y, aCentre.y );
242  }
243  else
244  {
245  MIRROR( m_Start0.x, aCentre.x );
246  MIRROR( m_End0.x, aCentre.x );
247  MIRROR( m_Bezier0_C1.x, aCentre.x );
248  MIRROR( m_Bezier0_C2.x, aCentre.x );
249  }
250 
251  for( unsigned ii = 0; ii < m_bezierPoints.size(); ii++ )
252  {
253  if( aMirrorAroundXAxis )
254  MIRROR( m_bezierPoints[ii].y, aCentre.y );
255  else
256  MIRROR( m_bezierPoints[ii].x, aCentre.x );
257  }
258 
259  break;
260 
261  case S_POLYGON:
262  // polygon corners coordinates are always relative to the
263  // footprint position, orientation 0
264  m_poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis );
265  break;
266  }
267 
268  SetDrawCoord();
269 }
270 
271 void FP_SHAPE::Rotate( const wxPoint& aRotCentre, double aAngle )
272 {
273  // We should rotate the relative coordinates, but to avoid duplicate code do the base class
274  // rotation of draw coordinates, which is acceptable because in the footprint editor
275  // m_Pos0 = m_Pos
276  PCB_SHAPE::Rotate( aRotCentre, aAngle );
277 
278  // and now update the relative coordinates, which are the reference in most transforms.
279  SetLocalCoord();
280 }
281 
282 
283 void FP_SHAPE::Move( const wxPoint& aMoveVector )
284 {
285  // Move an edge of the footprint.
286  // This is a footprint shape modification.
287  m_Start0 += aMoveVector;
288  m_End0 += aMoveVector;
289  m_ThirdPoint0 += aMoveVector;
290  m_Bezier0_C1 += aMoveVector;
291  m_Bezier0_C2 += aMoveVector;
292 
293  switch( GetShape() )
294  {
295  default:
296  break;
297 
298  case S_POLYGON:
299  // polygon corners coordinates are always relative to the
300  // footprint position, orientation 0
301  m_poly.Move( VECTOR2I( aMoveVector ) );
302 
303  break;
304  }
305 
306  SetDrawCoord();
307 }
308 
309 
310 double FP_SHAPE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
311 {
312  constexpr double HIDE = std::numeric_limits<double>::max();
313 
314  if( !aView )
315  return 0;
316 
317  // Handle Render tab switches
318  if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
319  return HIDE;
320 
321  if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
322  return HIDE;
323 
324  // Other layers are shown without any conditions
325  return 0.0;
326 }
327 
328 
329 static struct FP_SHAPE_DESC
330 {
332  {
336  }
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:162
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:64
#define TYPE_HASH(x)
Macro to generate unique identifier for a type
Definition: property.h:55
wxPoint m_end
Definition: pcb_shape.h:49
PNG memory record (file in memory).
Definition: bitmap_def.h:29
T NormalizeAngle360Max(T Angle)
Normalize angle to be >=-360.0 and <= 360.0 Angle can be equal to -360 or +360.
Definition: trigo.h:229
~FP_SHAPE()
Definition: fp_shape.cpp:48
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
Definition: board_item.h:206
PCB_SHAPE_TYPE_T m_shape
Definition: pcb_shape.h:52
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip entity relative to aCentre.
Definition: fp_shape.cpp:156
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
Definition: fp_shape.cpp:310
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:56
show footprints on back
double GetOrientation() const
Definition: footprint.h:204
static wxString ShowShape(PCB_SHAPE_TYPE_T aShape)
Function ShowShape converts 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:52
Arcs (with rounded ends)
Definition: board_item.h:54
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
#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:208
The base class for create windows for drawing purpose.
virtual void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
Definition: pcb_shape.cpp:197
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names
Definition: property_mgr.h:247
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirrors 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:154
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: fp_shape.cpp:135
PCB_SHAPE_TYPE_T
Enum PCB_SHAPE_TYPE_T is the set of shapes for PCB graphics and tracks and footprint graphics in the ...
Definition: board_item.h:50
#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:271
void SetAngle(double aAngle, bool aUpdateEnd=true) override
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: fp_shape.cpp:141
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: fp_shape.cpp:110
wxPoint m_End0
End point, relative to footprint origin, orient 0.
Definition: fp_shape.h:153
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declares an inheritance relationship between types.
wxPoint m_Start0
Start point or center, relative to footprint origin, orient 0.
Definition: fp_shape.h:152
double m_angle
Definition: pcb_shape.h:53
const wxString GetReference() const
Function GetReference.
Definition: footprint.h:440
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns 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:156
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Function Format outputs 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 Mirror(const wxPoint &aCentre, bool aMirrorAroundXAxis)
Mirror an edge of the footprint.
Definition: fp_shape.cpp:223
double GetAngle() const
Definition: pcb_shape.h:126
EDA_ITEM is a base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:148
wxPoint GetPosition() const override
Definition: footprint.h:200
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:317
PCB_LAYER_ID m_layer
Definition: board_item.h:89
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
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
Provides class metadata.
Definition: property_mgr.h:61
void Move(const wxPoint &aMoveVector) override
Move an edge of the footprint.
Definition: fp_shape.cpp:283
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:129
VIEW.
Definition: view.h:63
wxPoint m_Bezier0_C1
Bezier Control Point 1, relative to footprint origin, orient 0.
Definition: fp_shape.h:155
std::vector< wxPoint > m_bezierPoints
Definition: pcb_shape.h:57
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:179
wxPoint m_bezierC2
Definition: pcb_shape.h:55
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
Definition: board_item.cpp:60
Bezier Curve.
Definition: board_item.h:57
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: pcb_shape.cpp:466
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Definition: board_item.h:185
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:402