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 <view/view.h>
53 
54 #include <stdio.h>
55 
58 {
59  m_Shape = aShape;
60  m_Angle = 0;
61  m_Layer = F_SilkS;
62 }
63 
64 
66 {
67 }
68 
69 
71 {
72  MODULE* module = (MODULE*) m_Parent;
73 
74  if( module == NULL )
75  {
76  m_Start0 = m_Start;
77  m_End0 = m_End;
78  return;
79  }
80 
81  m_Start0 = m_Start - module->GetPosition();
82  m_End0 = m_End - module->GetPosition();
83  double angle = module->GetOrientation();
84  RotatePoint( &m_Start0.x, &m_Start0.y, -angle );
85  RotatePoint( &m_End0.x, &m_End0.y, -angle );
86 }
87 
88 
90 {
91  MODULE* module = (MODULE*) m_Parent;
92 
93  m_Start = m_Start0;
94  m_End = m_End0;
95 
96  if( module )
97  {
98  RotatePoint( &m_Start.x, &m_Start.y, module->GetOrientation() );
99  RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
100 
101  m_Start += module->GetPosition();
102  m_End += module->GetPosition();
103  }
104 }
105 
106 
107 void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
108  const wxPoint& offset )
109 {
110  int ux0, uy0, dx, dy, radius, StAngle, EndAngle;
111  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
112 
113  MODULE* module = (MODULE*) m_Parent;
114 
115  if( !module )
116  return;
117 
118  BOARD* brd = GetBoard( );
119 
120  if( brd->IsLayerVisible( m_Layer ) == false )
121  return;
122 
123 
124  auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
125  auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
126 
127  auto displ_opts = (PCB_DISPLAY_OPTIONS*)( panel->GetDisplayOptions() );
128 
129  if(( draw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay )
130  {
131  if( !IsOnLayer( curr_layer ) )
133  }
134 
135  ux0 = m_Start.x - offset.x;
136  uy0 = m_Start.y - offset.y;
137 
138  dx = m_End.x - offset.x;
139  dy = m_End.y - offset.y;
140 
141  GRSetDrawMode( DC, draw_mode );
142  bool filled = displ_opts ? displ_opts->m_DisplayModEdgeFill : FILLED;
143 
144  if( IsCopperLayer( m_Layer ) )
145  filled = displ_opts ? displ_opts->m_DisplayPcbTrackFill : FILLED;
146 
147  switch( m_Shape )
148  {
149  case S_SEGMENT:
150  if( filled )
151  GRLine( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
152  else
153  // SKETCH Mode
154  GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
155 
156  break;
157 
158  case S_CIRCLE:
159  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
160 
161  if( filled )
162  {
163  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color );
164  }
165  else // SKETCH Mode
166  {
167  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + (m_Width / 2), color );
168  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - (m_Width / 2), color );
169  }
170 
171  break;
172 
173  case S_ARC:
174  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
175  StAngle = ArcTangente( dy - uy0, dx - ux0 );
176  EndAngle = StAngle + m_Angle;
177 
178  if( !panel->GetPrintMirrored() )
179  {
180  if( StAngle > EndAngle )
181  std::swap( StAngle, EndAngle );
182  }
183  else // Mirrored mode: arc orientation is reversed
184  {
185  if( StAngle < EndAngle )
186  std::swap( StAngle, EndAngle );
187  }
188 
189  if( filled )
190  {
191  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius, m_Width, color );
192  }
193  else // SKETCH Mode
194  {
195  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
196  radius + (m_Width / 2), color );
197  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
198  radius - (m_Width / 2), color );
199  }
200  break;
201 
202  case S_POLYGON:
203  if( m_Poly.IsEmpty() )
204  break;
205 
206  {
207  // We must compute absolute coordinates from m_PolyPoints
208  // which are relative to module position, orientation 0
209  std::vector<wxPoint> points;
210 
211  for( auto iter = m_Poly.CIterate(); iter; iter++ )
212  {
213  points.push_back( wxPoint( iter->x,iter->y ) );
214  }
215 
216  for( unsigned ii = 0; ii < points.size(); ii++ )
217  {
218  wxPoint& pt = points[ii];
219 
220  RotatePoint( &pt.x, &pt.y, module->GetOrientation() );
221  pt += module->GetPosition() - offset;
222  }
223 
224  GRPoly( panel->GetClipBox(), DC, points.size(), &points[0], true, m_Width, color, color );
225  }
226  break;
227 
228  default:
229  break;
230  }
231 }
232 
233 
234 // see class_edge_mod.h
235 void EDGE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
236 {
237  wxString msg;
238 
239  MODULE* module = (MODULE*) m_Parent;
240 
241  if( !module )
242  return;
243 
244  BOARD* board = (BOARD*) module->GetParent();
245 
246  if( !board )
247  return;
248 
249  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), module->GetReference(), DARKCYAN ) );
250  aList.push_back( MSG_PANEL_ITEM( _( "Value" ), module->GetValue(), BLUE ) );
251  msg.Printf( wxT( "%8.8lX" ), module->GetTimeStamp() );
252  aList.push_back( MSG_PANEL_ITEM( _( "TimeStamp" ), msg, BROWN ) );
253  aList.push_back( MSG_PANEL_ITEM( _( "Footprint Layer" ),
254  module->GetLayerName(), RED ) );
255 
256  // append the features shared with the base class
258 }
259 
260 
261 
263 {
264  wxString text;
265  text.Printf( _( "Graphic (%s) on %s of %s" ),
266  GetChars( ShowShape( m_Shape ) ),
267  GetChars( GetLayerName() ),
268  GetChars( ((MODULE*) GetParent())->GetReference() ) );
269 
270  return text;
271 }
272 
273 
275 {
276  return show_mod_edge_xpm;
277 }
278 
279 
281 {
282  return new EDGE_MODULE( *this );
283 }
284 
285 
286 void EDGE_MODULE::Flip( const wxPoint& aCentre )
287 {
288  wxPoint pt;
289 
290  switch( GetShape() )
291  {
292  case S_ARC:
293  SetAngle( -GetAngle() );
294  //Fall through
295  default:
296  case S_SEGMENT:
297  pt = GetStart();
298  MIRROR( pt.y, aCentre.y );
299  SetStart( pt );
300 
301  pt = GetEnd();
302  MIRROR( pt.y, aCentre.y );
303  SetEnd( pt );
304 
305  MIRROR( m_Start0.y, 0 );
306  MIRROR( m_End0.y, 0 );
307  break;
308 
309  case S_POLYGON:
310  // polygon corners coordinates are always relative to the
311  // footprint position, orientation 0
312  for( auto iter = m_Poly.Iterate(); iter; iter++ )
313  {
314  MIRROR( iter->y, 0 );
315  }
316  break;
317  }
318 
319  // DRAWSEGMENT items are not usually on copper layers, but
320  // it can happen in microwave apps.
321  // However, currently, only on Front or Back layers.
322  // So the copper layers count is not taken in account
323  SetLayer( FlipLayer( GetLayer() ) );
324 }
325 
327 {
328  if( GetParent() && GetParent()->GetLayer() == B_Cu )
329  return true;
330  return false;
331 }
332 
333 void EDGE_MODULE::Mirror( wxPoint aCentre, bool aMirrorAroundXAxis )
334 {
335  // Mirror an edge of the footprint. the layer is not modified
336  // This is a footprint shape modification.
337  switch( GetShape() )
338  {
339  case S_ARC:
340  SetAngle( -GetAngle() );
341  //Fall through
342  default:
343  case S_SEGMENT:
344  if( aMirrorAroundXAxis )
345  {
346  MIRROR( m_Start0.y, aCentre.y );
347  MIRROR( m_End0.y, aCentre.y );
348  }
349  else
350  {
351  MIRROR( m_Start0.x, aCentre.x );
352  MIRROR( m_End0.x, aCentre.x );
353  }
354  break;
355 
356  case S_POLYGON:
357  // polygon corners coordinates are always relative to the
358  // footprint position, orientation 0
359  for( auto iter = m_Poly.Iterate(); iter; iter++ )
360  {
361  if( aMirrorAroundXAxis )
362  MIRROR( iter->y, aCentre.y );
363  else
364  MIRROR( iter->x, aCentre.x );
365  }
366  }
367 
368  SetDrawCoord();
369 }
370 
371 void EDGE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
372 {
373  // We should rotate the relative coordinates, but to avoid duplicate code,
374  // do the base class rotation of draw coordinates, which is acceptable
375  // because in module editor, m_Pos0 = m_Pos
376  DRAWSEGMENT::Rotate( aRotCentre, aAngle );
377 
378  // and now update the relative coordinates, which are
379  // the reference in most transforms.
380  SetLocalCoord();
381 }
382 
383 
384 void EDGE_MODULE::Move( const wxPoint& aMoveVector )
385 {
386  // Move an edge of the footprint.
387  // This is a footprint shape modification.
388  m_Start0 += aMoveVector;
389  m_End0 += aMoveVector;
390 
391  switch( GetShape() )
392  {
393  default:
394  break;
395 
396  case S_POLYGON:
397  // polygon corners coordinates are always relative to the
398  // footprint position, orientation 0
399  for( auto iter = m_Poly.Iterate(); iter; iter++ )
400  *iter += VECTOR2I( aMoveVector );
401  }
402 
403  SetDrawCoord();
404 }
405 
406 unsigned int EDGE_MODULE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
407 {
408  const int HIDE = std::numeric_limits<unsigned int>::max();
409 
410  if( !aView )
411  return 0;
412 
413  // Handle Render tab switches
414  if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
415  return HIDE;
416 
417  if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
418  return HIDE;
419 
420  // Other layers are shown without any conditions
421  return 0;
422 }
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:179
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
virtual unsigned int ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:318
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:106
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:404
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
show modules on back
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:486
usual segment : line with rounded ends
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
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.
show modules on front
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:170
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:187
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:180
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
#define max(a, b)
Definition: auxiliary.h:86
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:458
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)
bool IsParentFlipped() const
void SetDrawCoord()
Set draw coordinates (absolute values ) from relative coordinates.
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:193
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:162
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:187
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
Class VIEW.
Definition: view.h:58
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:182
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
timestamp_t GetTimeStamp() const
Definition: base_struct.h:215
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:454
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
Definition: colors.h:62