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 
41  PCB_SHAPE( parent, PCB_FP_SHAPE_T )
42 {
43  m_shape = aShape;
44  m_angle = 0;
45  m_layer = F_SilkS;
46 }
47 
48 
50 {
51 }
52 
53 
55 {
56  FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
57 
58  if( fp == NULL )
59  {
60  m_Start0 = m_start;
61  m_End0 = m_end;
65  return;
66  }
67 
68  m_Start0 = m_start - fp->GetPosition();
69  m_End0 = m_end - fp->GetPosition();
73  double angle = fp->GetOrientation();
74  RotatePoint( &m_Start0.x, &m_Start0.y, -angle );
75  RotatePoint( &m_End0.x, &m_End0.y, -angle );
79 }
80 
81 
83 {
84  FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
85 
86  m_start = m_Start0;
87  m_end = m_End0;
91 
92  if( fp )
93  {
94  RotatePoint( &m_start.x, &m_start.y, fp->GetOrientation() );
95  RotatePoint( &m_end.x, &m_end.y, fp->GetOrientation() );
99 
100  m_start += fp->GetPosition();
101  m_end += fp->GetPosition();
102  m_thirdPoint += fp->GetPosition();
103  m_bezierC1 += fp->GetPosition();
104  m_bezierC2 += fp->GetPosition();
105  }
106 
108 }
109 
110 
111 void FP_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
112 {
113  FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
114 
115  aList.emplace_back( _( "Footprint" ), fp ? fp->GetReference() : _( "<invalid>" ) );
116 
117  // append the features shared with the base class
118  PCB_SHAPE::GetMsgPanelInfo( aFrame, aList );
119 }
120 
121 
122 wxString FP_SHAPE::GetSelectMenuText( EDA_UNITS aUnits ) const
123 {
124  return wxString::Format( _( "%s on %s" ),
125  ShowShape( m_shape ),
126  GetLayerName() );
127 }
128 
129 
131 {
132  return BITMAPS::show_mod_edge;
133 }
134 
135 
137 {
138  return new FP_SHAPE( *this );
139 }
140 
141 
142 void FP_SHAPE::SetAngle( double aAngle, bool aUpdateEnd )
143 {
144  // Mark as depreciated.
145  // m_Angle does not define the arc anymore
146  // Update the parent class (updates the global m_ThirdPoint)
147  PCB_SHAPE::SetAngle( aAngle, aUpdateEnd );
148 
149  // Also update the local m_ThirdPoint0 if requested
150  if( aUpdateEnd )
151  {
154  }
155 }
156 
157 
158 void FP_SHAPE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
159 {
160  wxPoint pt( 0, 0 );
161 
162  switch( GetShape() )
163  {
164  case PCB_SHAPE_TYPE::ARC:
165  // Update arc angle but do not yet update m_ThirdPoint0 and m_thirdPoint,
166  // arc center and start point must be updated before calculation arc end.
167  SetAngle( -GetAngle(), false );
169 
170  default:
173  // If Start0 and Start are equal (ie: Footprint Editor), then flip both sets around the
174  // centre point.
175  if( m_start == m_Start0 )
176  pt = aCentre;
177 
178  if( aFlipLeftRight )
179  {
180  MIRROR( m_start.x, aCentre.x );
181  MIRROR( m_end.x, aCentre.x );
182  MIRROR( m_thirdPoint.x, aCentre.x );
183  MIRROR( m_bezierC1.x, aCentre.x );
184  MIRROR( m_bezierC2.x, aCentre.x );
185  MIRROR( m_Start0.x, pt.x );
186  MIRROR( m_End0.x, pt.x );
187  MIRROR( m_ThirdPoint0.x, pt.x );
188  MIRROR( m_Bezier0_C1.x, pt.x );
189  MIRROR( m_Bezier0_C2.x, pt.x );
190  }
191  else
192  {
193  MIRROR( m_start.y, aCentre.y );
194  MIRROR( m_end.y, aCentre.y );
195  MIRROR( m_thirdPoint.y, aCentre.y );
196  MIRROR( m_bezierC1.y, aCentre.y );
197  MIRROR( m_bezierC2.y, aCentre.y );
198  MIRROR( m_Start0.y, pt.y );
199  MIRROR( m_End0.y, pt.y );
200  MIRROR( m_ThirdPoint0.y, pt.y );
201  MIRROR( m_Bezier0_C1.y, pt.y );
202  MIRROR( m_Bezier0_C2.y, pt.y );
203  }
204 
206  break;
207 
209  // polygon corners coordinates are relative to the footprint position, orientation 0
210  m_poly.Mirror( aFlipLeftRight, !aFlipLeftRight );
211  break;
212  }
213 
214  SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
215 }
216 
218 {
219  if( GetParent() && GetParent()->GetLayer() == B_Cu )
220  return true;
221  return false;
222 }
223 
224 void FP_SHAPE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
225 {
226  // Mirror an edge of the footprint. the layer is not modified
227  // This is a footprint shape modification.
228 
229  switch( GetShape() )
230  {
231  case PCB_SHAPE_TYPE::ARC:
232  // Update arc angle but do not yet update m_ThirdPoint0 and m_thirdPoint,
233  // arc center and start point must be updated before calculation arc end.
234  SetAngle( -GetAngle(), false );
236 
237  default:
240  if( aMirrorAroundXAxis )
241  {
242  MIRROR( m_Start0.y, aCentre.y );
243  MIRROR( m_End0.y, aCentre.y );
244  MIRROR( m_ThirdPoint0.y, aCentre.y );
245  MIRROR( m_Bezier0_C1.y, aCentre.y );
246  MIRROR( m_Bezier0_C2.y, aCentre.y );
247  }
248  else
249  {
250  MIRROR( m_Start0.x, aCentre.x );
251  MIRROR( m_End0.x, aCentre.x );
252  MIRROR( m_ThirdPoint0.x, aCentre.x );
253  MIRROR( m_Bezier0_C1.x, aCentre.x );
254  MIRROR( m_Bezier0_C2.x, aCentre.x );
255  }
256 
257  for( unsigned ii = 0; ii < m_bezierPoints.size(); ii++ )
258  {
259  if( aMirrorAroundXAxis )
260  MIRROR( m_bezierPoints[ii].y, aCentre.y );
261  else
262  MIRROR( m_bezierPoints[ii].x, aCentre.x );
263  }
264 
265  break;
266 
268  // polygon corners coordinates are always relative to the
269  // footprint position, orientation 0
270  m_poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis );
271  break;
272  }
273 
274  SetDrawCoord();
275 }
276 
277 void FP_SHAPE::Rotate( const wxPoint& aRotCentre, double aAngle )
278 {
279  // We should rotate the relative coordinates, but to avoid duplicate code do the base class
280  // rotation of draw coordinates, which is acceptable because in the footprint editor
281  // m_Pos0 = m_Pos
282  PCB_SHAPE::Rotate( aRotCentre, aAngle );
283 
284  // and now update the relative coordinates, which are the reference in most transforms.
285  SetLocalCoord();
286 }
287 
288 
289 void FP_SHAPE::Move( const wxPoint& aMoveVector )
290 {
291  // Move an edge of the footprint.
292  // This is a footprint shape modification.
293  m_Start0 += aMoveVector;
294  m_End0 += aMoveVector;
295  m_ThirdPoint0 += aMoveVector;
296  m_Bezier0_C1 += aMoveVector;
297  m_Bezier0_C2 += aMoveVector;
298 
299  switch( GetShape() )
300  {
301  default:
302  break;
303 
305  // polygon corners coordinates are always relative to the
306  // footprint position, orientation 0
307  m_poly.Move( VECTOR2I( aMoveVector ) );
308 
309  break;
310  }
311 
312  SetDrawCoord();
313 }
314 
315 
316 double FP_SHAPE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
317 {
318  constexpr double HIDE = std::numeric_limits<double>::max();
319 
320  if( !aView )
321  return 0;
322 
323  // Handle Render tab switches
324  if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
325  return HIDE;
326 
327  if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
328  return HIDE;
329 
330  // Other layers are shown without any conditions
331  return 0.0;
332 }
333 
334 
335 static struct FP_SHAPE_DESC
336 {
338  {
342 
343  propMgr.AddProperty( new PROPERTY<FP_SHAPE, wxString>( _HKI( "Parent" ),
345  }
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:529
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:65
#define TYPE_HASH(x)
Definition: property.h:59
wxPoint m_end
Definition: pcb_shape.h:49
~FP_SHAPE()
Definition: fp_shape.cpp:49
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:194
PCB_SHAPE_TYPE GetShape() const
Definition: pcb_shape.h:130
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:158
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: fp_shape.cpp:316
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:521
show footprints on back
double GetOrientation() const
Definition: footprint.h:186
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
PCB_SHAPE_TYPE
The set of shapes for PCB graphics and tracks and footprint graphics in the .m_Shape member.
Definition: board_item.h:48
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:198
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
#define NO_SETTER(owner, type)
Definition: property.h:621
FP_SHAPE(FOOTPRINT *parent, PCB_SHAPE_TYPE aShape=PCB_SHAPE_TYPE::SEGMENT)
Definition: fp_shape.cpp:40
#define REGISTER_TYPE(x)
Definition: property_mgr.h:248
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.
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
polygon (not yet used for tracks, but could be in microwave apps)
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:136
#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:277
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:142
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:111
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:426
double m_angle
Definition: pcb_shape.h:53
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
Definition: fp_shape.cpp:82
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: fp_shape.cpp:130
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:217
int m_width
Definition: pcb_shape.h:46
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:32
#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:224
double GetAngle() const
Definition: pcb_shape.h:127
usual segment : line with rounded ends
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
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:316
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:122
wxPoint m_bezierC1
Definition: pcb_shape.h:54
void SetLocalCoord()
Set relative coordinates from draw coordinates.
Definition: fp_shape.cpp:54
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:289
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
static wxString ShowShape(PCB_SHAPE_TYPE aShape)
Convert the enum #PCB_SHAPE_TYPE_T integer value to a wxString.
Definition: board_item.cpp:31
Arcs (with rounded ends)
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:466
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
PCB_SHAPE_TYPE m_shape
Definition: pcb_shape.h:52
#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:488
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