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 
32 #include <fctsys.h>
33 #include <gr_basic.h>
34 #include <trigo.h>
35 #include <class_drawpanel.h>
36 #include <pcb_screen.h>
37 #include <confirm.h>
38 #include <kicad_string.h>
39 #include <richio.h>
40 #include <macros.h>
41 #include <math_for_graphics.h>
42 #include <pcb_base_frame.h>
43 #include <msgpanel.h>
44 #include <base_units.h>
45 #include <bitmaps.h>
46 
47 #include <pcb_edit_frame.h>
48 #include <class_board.h>
49 #include <class_module.h>
50 #include <class_edge_mod.h>
51 
52 #include <stdio.h>
53 
56 {
57  m_Shape = aShape;
58  m_Angle = 0;
59  m_Layer = F_SilkS;
60 }
61 
62 
64 {
65 }
66 
67 
69 {
70  MODULE* module = (MODULE*) m_Parent;
71 
72  if( module == NULL )
73  {
74  m_Start0 = m_Start;
75  m_End0 = m_End;
76  return;
77  }
78 
79  m_Start0 = m_Start - module->GetPosition();
80  m_End0 = m_End - module->GetPosition();
81  double angle = module->GetOrientation();
82  RotatePoint( &m_Start0.x, &m_Start0.y, -angle );
83  RotatePoint( &m_End0.x, &m_End0.y, -angle );
84 }
85 
86 
88 {
89  MODULE* module = (MODULE*) m_Parent;
90 
91  m_Start = m_Start0;
92  m_End = m_End0;
93 
94  if( module )
95  {
96  RotatePoint( &m_Start.x, &m_Start.y, module->GetOrientation() );
97  RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
98 
99  m_Start += module->GetPosition();
100  m_End += module->GetPosition();
101  }
102 }
103 
104 
105 void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
106  const wxPoint& offset )
107 {
108  int ux0, uy0, dx, dy, radius, StAngle, EndAngle;
109  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
110 
111  MODULE* module = (MODULE*) m_Parent;
112 
113  if( !module )
114  return;
115 
116  BOARD* brd = GetBoard( );
117 
118  if( brd->IsLayerVisible( m_Layer ) == false )
119  return;
120 
121 
122  auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
123  auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
124 
125  auto displ_opts = (PCB_DISPLAY_OPTIONS*)( panel->GetDisplayOptions() );
126 
127  if(( draw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay )
128  {
129  if( !IsOnLayer( curr_layer ) )
131  }
132 
133  ux0 = m_Start.x - offset.x;
134  uy0 = m_Start.y - offset.y;
135 
136  dx = m_End.x - offset.x;
137  dy = m_End.y - offset.y;
138 
139  GRSetDrawMode( DC, draw_mode );
140  bool filled = displ_opts ? displ_opts->m_DisplayModEdgeFill : FILLED;
141 
142  if( IsCopperLayer( m_Layer ) )
143  filled = displ_opts ? displ_opts->m_DisplayPcbTrackFill : FILLED;
144 
145  switch( m_Shape )
146  {
147  case S_SEGMENT:
148  if( filled )
149  GRLine( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
150  else
151  // SKETCH Mode
152  GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
153 
154  break;
155 
156  case S_CIRCLE:
157  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
158 
159  if( filled )
160  {
161  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color );
162  }
163  else // SKETCH Mode
164  {
165  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + (m_Width / 2), color );
166  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - (m_Width / 2), color );
167  }
168 
169  break;
170 
171  case S_ARC:
172  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
173  StAngle = ArcTangente( dy - uy0, dx - ux0 );
174  EndAngle = StAngle + m_Angle;
175 
176  if( !panel->GetPrintMirrored() )
177  {
178  if( StAngle > EndAngle )
179  std::swap( StAngle, EndAngle );
180  }
181  else // Mirrored mode: arc orientation is reversed
182  {
183  if( StAngle < EndAngle )
184  std::swap( StAngle, EndAngle );
185  }
186 
187  if( filled )
188  {
189  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius, m_Width, color );
190  }
191  else // SKETCH Mode
192  {
193  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
194  radius + (m_Width / 2), color );
195  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
196  radius - (m_Width / 2), color );
197  }
198  break;
199 
200  case S_POLYGON:
201  if( m_Poly.IsEmpty() )
202  break;
203 
204  {
205  // We must compute absolute coordinates from m_PolyPoints
206  // which are relative to module position, orientation 0
207  std::vector<wxPoint> points;
208 
209  for( auto iter = m_Poly.CIterate(); iter; iter++ )
210  {
211  points.push_back( wxPoint( iter->x,iter->y ) );
212  }
213 
214  for( unsigned ii = 0; ii < points.size(); ii++ )
215  {
216  wxPoint& pt = points[ii];
217 
218  RotatePoint( &pt.x, &pt.y, module->GetOrientation() );
219  pt += module->GetPosition() - offset;
220  }
221 
222  GRPoly( panel->GetClipBox(), DC, points.size(), &points[0], true, m_Width, color, color );
223  }
224  break;
225 
226  default:
227  break;
228  }
229 }
230 
231 
232 // see class_edge_mod.h
233 void EDGE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
234 {
235  wxString msg;
236 
237  MODULE* module = (MODULE*) m_Parent;
238 
239  if( !module )
240  return;
241 
242  BOARD* board = (BOARD*) module->GetParent();
243 
244  if( !board )
245  return;
246 
247  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), module->GetReference(), DARKCYAN ) );
248  aList.push_back( MSG_PANEL_ITEM( _( "Value" ), module->GetValue(), BLUE ) );
249  msg.Printf( wxT( "%8.8lX" ), module->GetTimeStamp() );
250  aList.push_back( MSG_PANEL_ITEM( _( "TimeStamp" ), msg, BROWN ) );
251  aList.push_back( MSG_PANEL_ITEM( _( "Footprint Layer" ),
252  module->GetLayerName(), RED ) );
253 
254  // append the features shared with the base class
256 }
257 
258 
259 
261 {
262  wxString text;
263  text.Printf( _( "Graphic (%s) on %s of %s" ),
264  GetChars( ShowShape( m_Shape ) ),
265  GetChars( GetLayerName() ),
266  GetChars( ((MODULE*) GetParent())->GetReference() ) );
267 
268  return text;
269 }
270 
271 
273 {
274  return show_mod_edge_xpm;
275 }
276 
277 
279 {
280  return new EDGE_MODULE( *this );
281 }
282 
283 
284 void EDGE_MODULE::Flip( const wxPoint& aCentre )
285 {
286  wxPoint pt;
287 
288  switch( GetShape() )
289  {
290  case S_ARC:
291  SetAngle( -GetAngle() );
292  //Fall through
293  default:
294  case S_SEGMENT:
295  pt = GetStart();
296  MIRROR( pt.y, aCentre.y );
297  SetStart( pt );
298 
299  pt = GetEnd();
300  MIRROR( pt.y, aCentre.y );
301  SetEnd( pt );
302 
303  MIRROR( m_Start0.y, 0 );
304  MIRROR( m_End0.y, 0 );
305  break;
306 
307  case S_POLYGON:
308  // polygon corners coordinates are always relative to the
309  // footprint position, orientation 0
310  for( auto iter = m_Poly.Iterate(); iter; iter++ )
311  {
312  MIRROR( iter->y, 0 );
313  }
314  break;
315  }
316 
317  // DRAWSEGMENT items are not usually on copper layers, but
318  // it can happen in microwave apps.
319  // However, currently, only on Front or Back layers.
320  // So the copper layers count is not taken in account
321  SetLayer( FlipLayer( GetLayer() ) );
322 }
323 
324 
325 void EDGE_MODULE::Mirror( wxPoint aCentre, bool aMirrorAroundXAxis )
326 {
327  // Mirror an edge of the footprint. the layer is not modified
328  // This is a footprint shape modification.
329  switch( GetShape() )
330  {
331  case S_ARC:
332  SetAngle( -GetAngle() );
333  //Fall through
334  default:
335  case S_SEGMENT:
336  if( aMirrorAroundXAxis )
337  {
338  MIRROR( m_Start0.y, aCentre.y );
339  MIRROR( m_End0.y, aCentre.y );
340  }
341  else
342  {
343  MIRROR( m_Start0.x, aCentre.x );
344  MIRROR( m_End0.x, aCentre.x );
345  }
346  break;
347 
348  case S_POLYGON:
349  // polygon corners coordinates are always relative to the
350  // footprint position, orientation 0
351  for( auto iter = m_Poly.Iterate(); iter; iter++ )
352  {
353  if( aMirrorAroundXAxis )
354  MIRROR( iter->y, aCentre.y );
355  else
356  MIRROR( iter->x, aCentre.x );
357  }
358  }
359 
360  SetDrawCoord();
361 }
362 
363 void EDGE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
364 {
365  // We should rotate the relative coordinates, but to avoid duplicate code,
366  // do the base class rotation of draw coordinates, which is acceptable
367  // because in module editor, m_Pos0 = m_Pos
368  DRAWSEGMENT::Rotate( aRotCentre, aAngle );
369 
370  // and now update the relative coordinates, which are
371  // the reference in most transforms.
372  SetLocalCoord();
373 }
374 
375 
376 void EDGE_MODULE::Move( const wxPoint& aMoveVector )
377 {
378  // Move an edge of the footprint.
379  // This is a footprint shape modification.
380  m_Start0 += aMoveVector;
381  m_End0 += aMoveVector;
382 
383  switch( GetShape() )
384  {
385  default:
386  break;
387 
388  case S_POLYGON:
389  // polygon corners coordinates are always relative to the
390  // footprint position, orientation 0
391  for( auto iter = m_Poly.Iterate(); iter; iter++ )
392  *iter += VECTOR2I( aMoveVector );
393  }
394 
395  SetDrawCoord();
396 }
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it&#39;s internal state for displ...
Definition: colors.h:57
BOARD_ITEM_CONTAINER * GetParent() const
static wxString ShowShape(STROKE_T aShape)
Function ShowShape converts the enum STROKE_T integer value to a wxString.
void GRPoly(EDA_RECT *ClipBox, wxDC *DC, int n, wxPoint Points[], bool Fill, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:796
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:197
virtual void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it&#39;s internal state for displ...
PNG memory record (file in memory).
Definition: bitmap_types.h:41
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:318
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Function IsOnLayer tests to see if this object is on the given layer.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Class BOARD to handle a board.
SHAPE_POLY_SET m_Poly
Stores the S_POLYGON shape.
int color
Definition: DXF_plotter.cpp:62
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:472
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
void GRCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, int aPenSize, COLOR4D Color)
Definition: gr_basic.cpp:510
const wxString & GetValue() const
Function GetValue.
Definition: class_module.h:467
usual segment : line with rounded ends
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
double m_Angle
Used only for Arcs: Arc angle in 1/10 deg.
ITERATOR Iterate(int aFirst, int aLast, bool aIterateHoles=false)
Function Iterate returns an object to iterate through the points of the polygons between aFirst and a...
VECTOR2< int > VECTOR2I
Definition: vector2d.h:589
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
wxPoint m_End0
This file contains miscellaneous commonly used macros and functions.
Classes used in Pcbnew, CvPcb and GerbView.
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate an edge of the footprint.
PCB_LAYER_ID m_Layer
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:111
void Mirror(const wxPoint aCentre, bool aMirrorAroundXAxis)
Mirror an edge of the footprint.
Class PCB_DISPLAY_OPTIONS handles display options like enable/disable some optional drawings...
PCB_LAYER_ID
A quick note on layer IDs:
STROKE_T GetShape() const
wxPoint m_Start
Line start point or Circle and Arc center.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:271
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.
double GetOrientation() const
Definition: class_module.h:180
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:37
Arcs (with rounded ends)
void GRArc(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, double StAngle, double EndAngle, int r, COLOR4D Color)
Definition: gr_basic.cpp:1003
STROKE_T
Enum STROKE_T is the set of shapes for segments (graphic segments and tracks) which are often in the ...
EDA_RECT * GetClipBox()
STROKE_T m_Shape
Shape: line, Circle, Arc.
Definition: colors.h:60
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
EDA_DRAW_FRAME * GetParent() const
Definition: draw_panel.cpp:181
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:380
void Flip(const wxPoint &aCentre) override
Flip entity relative to aCentre.
void SetStart(const wxPoint &aStart)
void SetLocalCoord()
Set relative coordinates from draw coordinates.
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.
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
double GetAngle() const
bool GetPrintMirrored() const
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:439
void Move(const wxPoint &aMoveVector) override
Move an edge of the footprint.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, COLOR4D Color)
Definition: gr_basic.cpp:850
EDGE_MODULE(MODULE *parent, STROKE_T aShape=S_SEGMENT)
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:194
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:180
void SetEnd(const wxPoint &aEnd)
void SetAngle(double aAngle)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees...
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
int m_Width
thickness of lines ...
Module description (excepted pads)
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
wxPoint m_Start0
void * GetDisplayOptions()
Function GetDisplayOptions A way to pass info to draw functions.
Definition: draw_panel.cpp:188
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
double Distance(double x1, double y1, double x2, double y2)
EDGE_MODULE class definition.
Message panel definition file.
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
const wxPoint GetPosition() const override
Definition: class_module.h:175
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
timestamp_t GetTimeStamp() const
Definition: base_struct.h:233
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
Function IsLayerVisible is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:451
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
Definition: colors.h:62