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;
63  return;
64  }
65 
66  m_Start0 = m_Start - module->GetPosition();
67  m_End0 = m_End - module->GetPosition();
68  m_Bezier0_C1 = m_BezierC1 - module->GetPosition();
69  m_Bezier0_C2 = m_BezierC2 - module->GetPosition();
70  double angle = module->GetOrientation();
72  RotatePoint( &m_End0.x, &m_End0.y, -angle );
75 }
76 
77 
79 {
80  MODULE* module = (MODULE*) m_Parent;
81 
82  m_Start = m_Start0;
83  m_End = m_End0;
86 
87  if( module )
88  {
89  RotatePoint( &m_Start.x, &m_Start.y, module->GetOrientation() );
90  RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
93 
94  m_Start += module->GetPosition();
95  m_End += module->GetPosition();
96  m_BezierC1 += module->GetPosition();
97  m_BezierC2 += module->GetPosition();
98  }
99 
101 }
102 
103 
104 // see class_edge_mod.h
105 void EDGE_MODULE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
106 {
107  wxString msg;
108 
109  MODULE* module = (MODULE*) m_Parent;
110 
111  if( !module )
112  return;
113 
114  BOARD* board = (BOARD*) module->GetParent();
115 
116  if( !board )
117  return;
118 
119  aList.emplace_back( _( "Footprint" ), module->GetReference(), DARKCYAN );
120 
121  // append the features shared with the base class
122  DRAWSEGMENT::GetMsgPanelInfo( aFrame, aList );
123 }
124 
125 
127 {
128  return wxString::Format( _( "Graphic %s of %s on %s" ),
129  ShowShape( m_Shape ),
130  ((MODULE*) GetParent())->GetReference(),
131  GetLayerName() );
132 }
133 
134 
136 {
137  return show_mod_edge_xpm;
138 }
139 
140 
142 {
143  return new EDGE_MODULE( *this );
144 }
145 
146 
147 void EDGE_MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
148 {
149  wxPoint pt( 0, 0 );
150 
151  switch( GetShape() )
152  {
153  case S_ARC:
154  SetAngle( -GetAngle() );
156 
157  default:
158  case S_SEGMENT:
159  case S_CURVE:
160  // If Start0 and Start are equal (ie: ModEdit), then flip both sets around the
161  // centre point.
162  if( m_Start == m_Start0 )
163  pt = aCentre;
164 
165  if( aFlipLeftRight )
166  {
167  MIRROR( m_Start.x, aCentre.x );
168  MIRROR( m_End.x, aCentre.x );
169  MIRROR( m_BezierC1.x, aCentre.x );
170  MIRROR( m_BezierC2.x, aCentre.x );
171  MIRROR( m_Start0.x, pt.x );
172  MIRROR( m_End0.x, pt.x );
173  MIRROR( m_Bezier0_C1.x, pt.x );
174  MIRROR( m_Bezier0_C2.x, pt.x );
175  }
176  else
177  {
178  MIRROR( m_Start.y, aCentre.y );
179  MIRROR( m_End.y, aCentre.y );
180  MIRROR( m_BezierC1.y, aCentre.y );
181  MIRROR( m_BezierC2.y, aCentre.y );
182  MIRROR( m_Start0.y, pt.y );
183  MIRROR( m_End0.y, pt.y );
184  MIRROR( m_Bezier0_C1.y, pt.y );
185  MIRROR( m_Bezier0_C2.y, pt.y );
186  }
187 
189  break;
190 
191  case S_POLYGON:
192  // polygon corners coordinates are relative to the footprint position, orientation 0
193  m_Poly.Mirror( aFlipLeftRight, !aFlipLeftRight );
194  break;
195  }
196 
197  // DRAWSEGMENT items are not usually on copper layers, but it can happen in microwave apps.
198  // However, currently, only on Front or Back layers.
199  // So the copper layers count is not taken in account
200  SetLayer( FlipLayer( GetLayer() ) );
201 }
202 
204 {
205  if( GetParent() && GetParent()->GetLayer() == B_Cu )
206  return true;
207  return false;
208 }
209 
210 void EDGE_MODULE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
211 {
212  // Mirror an edge of the footprint. the layer is not modified
213  // This is a footprint shape modification.
214  switch( GetShape() )
215  {
216  case S_ARC:
217  SetAngle( -GetAngle() );
219 
220  default:
221  case S_CURVE:
222  case S_SEGMENT:
223  if( aMirrorAroundXAxis )
224  {
225  MIRROR( m_Start0.y, aCentre.y );
226  MIRROR( m_End0.y, aCentre.y );
227  MIRROR( m_Bezier0_C1.y, aCentre.y );
228  MIRROR( m_Bezier0_C2.y, aCentre.y );
229  }
230  else
231  {
232  MIRROR( m_Start0.x, aCentre.x );
233  MIRROR( m_End0.x, aCentre.x );
234  MIRROR( m_Bezier0_C1.x, aCentre.x );
235  MIRROR( m_Bezier0_C2.x, aCentre.x );
236  }
237 
238  for( unsigned ii = 0; ii < m_BezierPoints.size(); ii++ )
239  {
240  if( aMirrorAroundXAxis )
241  MIRROR( m_BezierPoints[ii].y, aCentre.y );
242  else
243  MIRROR( m_BezierPoints[ii].x, aCentre.x );
244  }
245 
246  break;
247 
248  case S_POLYGON:
249  // polygon corners coordinates are always relative to the
250  // footprint position, orientation 0
251  m_Poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis );
252  break;
253  }
254 
255  SetDrawCoord();
256 }
257 
258 void EDGE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
259 {
260  // We should rotate the relative coordinates, but to avoid duplicate code do the base class
261  // rotation of draw coordinates, which is acceptable because in module editor, m_Pos0 = m_Pos
262  DRAWSEGMENT::Rotate( aRotCentre, aAngle );
263 
264  // and now update the relative coordinates, which are the reference in most transforms.
265  SetLocalCoord();
266 }
267 
268 
269 void EDGE_MODULE::Move( const wxPoint& aMoveVector )
270 {
271  // Move an edge of the footprint.
272  // This is a footprint shape modification.
273  m_Start0 += aMoveVector;
274  m_End0 += aMoveVector;
275  m_Bezier0_C1 += aMoveVector;
276  m_Bezier0_C2 += aMoveVector;
277 
278  switch( GetShape() )
279  {
280  default:
281  break;
282 
283  case S_POLYGON:
284  // polygon corners coordinates are always relative to the
285  // footprint position, orientation 0
286  m_Poly.Move( VECTOR2I( aMoveVector ) );
287 
288  break;
289  }
290 
291  SetDrawCoord();
292 }
293 
294 
295 unsigned int EDGE_MODULE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
296 {
297  const int HIDE = std::numeric_limits<unsigned int>::max();
298 
299  if( !aView )
300  return 0;
301 
302  // Handle Render tab switches
303  if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
304  return HIDE;
305 
306  if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
307  return HIDE;
308 
309  // Other layers are shown without any conditions
310  return 0;
311 }
312 
313 
314 static struct EDGE_MODULE_DESC
315 {
317  {
321  }
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:211
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
#define KI_FALLTHROUGH
PNG memory record (file in memory).
Definition: bitmap_def.h:29
virtual unsigned int ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
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...
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)
Function FlippedLayerNumber.
Definition: lset.cpp:485
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
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
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:433
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_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.
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.
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:205
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:180
#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.
void SetAngle(double aAngle)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Provides class metadata.
Definition: property_mgr.h:58
wxPoint GetPosition() const override
Definition: class_module.h:206
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:416
std::vector< wxPoint > m_BezierPoints