KiCad PCB EDA Suite
class_edge_mod.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 <fctsys.h>
28 #include <bitmaps.h>
29 #include <math/util.h> // for KiROUND
32 #include <pcb_edit_frame.h>
33 #include <class_board.h>
34 #include <class_module.h>
35 #include <class_edge_mod.h>
36 #include <view/view.h>
37 
38 
41 {
42  m_Shape = aShape;
43  m_Angle = 0;
44  m_Layer = F_SilkS;
45 }
46 
47 
49 {
50 }
51 
52 
54 {
55  MODULE* module = (MODULE*) m_Parent;
56 
57  if( module == NULL )
58  {
59  m_Start0 = m_Start;
60  m_End0 = m_End;
64  return;
65  }
66 
67  m_Start0 = m_Start - module->GetPosition();
68  m_End0 = m_End - module->GetPosition();
70  m_Bezier0_C1 = m_BezierC1 - module->GetPosition();
71  m_Bezier0_C2 = m_BezierC2 - module->GetPosition();
72  double angle = module->GetOrientation();
74  RotatePoint( &m_End0.x, &m_End0.y, -angle );
78 }
79 
80 
82 {
83  MODULE* module = (MODULE*) m_Parent;
84 
85  m_Start = m_Start0;
86  m_End = m_End0;
90 
91  if( module )
92  {
93  RotatePoint( &m_Start.x, &m_Start.y, module->GetOrientation() );
94  RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
98 
99  m_Start += module->GetPosition();
100  m_End += module->GetPosition();
101  m_ThirdPoint += module->GetPosition();
102  m_BezierC1 += module->GetPosition();
103  m_BezierC2 += module->GetPosition();
104  }
105 
107 }
108 
109 
110 // see class_edge_mod.h
111 void EDGE_MODULE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
112 {
113  wxString msg;
114 
115  MODULE* module = (MODULE*) m_Parent;
116 
117  if( !module )
118  return;
119 
120  BOARD* board = (BOARD*) module->GetParent();
121 
122  if( !board )
123  return;
124 
125  aList.emplace_back( _( "Footprint" ), module->GetReference(), DARKCYAN );
126 
127  // append the features shared with the base class
128  DRAWSEGMENT::GetMsgPanelInfo( aFrame, aList );
129 }
130 
131 
133 {
134  return wxString::Format( _( "%s on %s" ),
135  ShowShape( m_Shape ),
136  GetLayerName() );
137 }
138 
139 
141 {
142  return show_mod_edge_xpm;
143 }
144 
145 
147 {
148  return new EDGE_MODULE( *this );
149 }
150 
151 
152 void EDGE_MODULE::SetAngle( double aAngle )
153 {
154  // Mark as depreciated.
155  // m_Angle does not define the arc anymore
156  // m_Angle must be >= -360 and <= +360 degrees
157  m_Angle = NormalizeAngle360Max( aAngle );
160 }
161 
162 
163 void EDGE_MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
164 {
165  wxPoint pt( 0, 0 );
166 
167  switch( GetShape() )
168  {
169  case S_ARC:
170  SetAngle( -GetAngle() );
172 
173  default:
174  case S_SEGMENT:
175  case S_CURVE:
176  // If Start0 and Start are equal (ie: ModEdit), then flip both sets around the
177  // centre point.
178  if( m_Start == m_Start0 )
179  pt = aCentre;
180 
181  if( aFlipLeftRight )
182  {
183  MIRROR( m_Start.x, aCentre.x );
184  MIRROR( m_End.x, aCentre.x );
185  MIRROR( m_ThirdPoint.x, aCentre.x );
186  MIRROR( m_BezierC1.x, aCentre.x );
187  MIRROR( m_BezierC2.x, aCentre.x );
188  MIRROR( m_Start0.x, pt.x );
189  MIRROR( m_End0.x, pt.x );
190  MIRROR( m_ThirdPoint0.x, pt.x );
191  MIRROR( m_Bezier0_C1.x, pt.x );
192  MIRROR( m_Bezier0_C2.x, pt.x );
193  }
194  else
195  {
196  MIRROR( m_Start.y, aCentre.y );
197  MIRROR( m_End.y, aCentre.y );
198  MIRROR( m_ThirdPoint.y, aCentre.y );
199  MIRROR( m_BezierC1.y, aCentre.y );
200  MIRROR( m_BezierC2.y, aCentre.y );
201  MIRROR( m_Start0.y, pt.y );
202  MIRROR( m_End0.y, pt.y );
203  MIRROR( m_ThirdPoint0.y, pt.y );
204  MIRROR( m_Bezier0_C1.y, pt.y );
205  MIRROR( m_Bezier0_C2.y, pt.y );
206  }
207 
209  break;
210 
211  case S_POLYGON:
212  // polygon corners coordinates are relative to the footprint position, orientation 0
213  m_Poly.Mirror( aFlipLeftRight, !aFlipLeftRight );
214  break;
215  }
216 
217  // DRAWSEGMENT items are not usually on copper layers, but it can happen in microwave apps.
218  // However, currently, only on Front or Back layers.
219  // So the copper layers count is not taken in account
220  SetLayer( FlipLayer( GetLayer() ) );
221 }
222 
224 {
225  if( GetParent() && GetParent()->GetLayer() == B_Cu )
226  return true;
227  return false;
228 }
229 
230 void EDGE_MODULE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
231 {
232  // Mirror an edge of the footprint. the layer is not modified
233  // This is a footprint shape modification.
234  switch( GetShape() )
235  {
236  case S_ARC:
237  SetAngle( -GetAngle() );
239 
240  default:
241  case S_CURVE:
242  case S_SEGMENT:
243  if( aMirrorAroundXAxis )
244  {
245  MIRROR( m_Start0.y, aCentre.y );
246  MIRROR( m_End0.y, aCentre.y );
247  MIRROR( m_Bezier0_C1.y, aCentre.y );
248  MIRROR( m_Bezier0_C2.y, aCentre.y );
249  }
250  else
251  {
252  MIRROR( m_Start0.x, aCentre.x );
253  MIRROR( m_End0.x, aCentre.x );
254  MIRROR( m_Bezier0_C1.x, aCentre.x );
255  MIRROR( m_Bezier0_C2.x, aCentre.x );
256  }
257 
258  for( unsigned ii = 0; ii < m_BezierPoints.size(); ii++ )
259  {
260  if( aMirrorAroundXAxis )
261  MIRROR( m_BezierPoints[ii].y, aCentre.y );
262  else
263  MIRROR( m_BezierPoints[ii].x, aCentre.x );
264  }
265 
266  break;
267 
268  case S_POLYGON:
269  // polygon corners coordinates are always relative to the
270  // footprint position, orientation 0
271  m_Poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis );
272  break;
273  }
274 
275  SetDrawCoord();
276 }
277 
278 void EDGE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
279 {
280  // We should rotate the relative coordinates, but to avoid duplicate code do the base class
281  // rotation of draw coordinates, which is acceptable because in module editor, m_Pos0 = m_Pos
282  DRAWSEGMENT::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 EDGE_MODULE::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 
304  case S_POLYGON:
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 EDGE_MODULE::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 EDGE_MODULE_DESC
336 {
338  {
342  }
EDA_UNITS
Definition: common.h:198
wxPoint m_Bezier0_C2
Bezier Control Point 2, relative to module origin, orient 0.
static wxString ShowShape(STROKE_T aShape)
Function ShowShape converts the enum STROKE_T integer value to a wxString.
double GetOrientation() const
Definition: class_module.h:224
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:61
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:174
#define TYPE_HASH(x)
Macro to generate unique identifier for a type
Definition: property.h:53
PNG memory record (file in memory).
Definition: bitmap_def.h:29
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...
T NormalizeAngle360Max(T Angle)
Normalize angle to be >=-360.0 and <= 360.0 Angle can be equal to -360 or +360.
Definition: trigo.h:231
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
STROKE_T GetShape() const
SHAPE_POLY_SET m_Poly
Stores the S_POLYGON shape.
polygon (not yet used for tracks, but could be in microwave apps)
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:520
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_BezierPoints vertex list that approximate the Bezier curve by a list of segments Has me...
usual segment : line with rounded ends
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:88
static struct EDGE_MODULE_DESC _EDGE_MODULE_DESC
double m_Angle
Used only for Arcs: Arc angle in 1/10 deg.
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
The base class for create windows for drawing purpose.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names
Definition: property_mgr.h:244
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
Mirrors the line points about y or x (or both)
wxPoint m_End0
End point, relative to module origin, orient 0.
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
wxPoint m_BezierC1
Bezier Control Point 1.
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:451
wxPoint m_Bezier0_C1
Bezier Control Point 1, relative to module origin, orient 0.
show modules on front
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
bool IsParentFlipped() const
PCB_LAYER_ID m_Layer
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:175
wxPoint m_Start
Line start point or Circle and Arc center.
#define NULL
void Move(const VECTOR2I &aVector) override
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
wxPoint m_ThirdPoint
Used only for Arcs: arc end point.
wxPoint m_End
Line end point or circle and arc start point.
Arcs (with rounded ends)
void Mirror(const wxPoint &aCentre, bool aMirrorAroundXAxis)
Mirror an edge of the footprint.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declares an inheritance relationship between types.
void SetAngle(double aAngle) override
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
STROKE_T
Enum STROKE_T is the set of shapes for segments (graphic segments and tracks) which are often in the ...
STROKE_T m_Shape
Shape: line, Circle, Arc.
Bezier Curve.
void SetLocalCoord()
Set relative coordinates from draw coordinates.
double GetAngle() const
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
wxPoint m_ThirdPoint0
End point for an arc.
virtual void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
const BITMAP_OPAQUE show_mod_edge_xpm[1]
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:201
Information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:176
#define _(s)
Definition: 3d_actions.cpp:33
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...
void Move(const wxPoint &aMoveVector) override
Move an edge of the footprint.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
EDGE_MODULE(MODULE *parent, STROKE_T aShape=S_SEGMENT)
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
wxPoint m_BezierC2
Bezier Control Point 2.
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip entity relative to aCentre.
Provides class metadata.
Definition: property_mgr.h:58
wxPoint GetPosition() const override
Definition: class_module.h:219
int m_Width
thickness of lines ...
wxPoint m_Start0
Start point or center, relative to module origin, orient 0.
VIEW.
Definition: view.h:61
EDGE_MODULE class definition.
BOARD_ITEM_CONTAINER * GetParent() const
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:405
std::vector< wxPoint > m_BezierPoints