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 <wxstruct.h>
35 #include <trigo.h>
36 #include <class_drawpanel.h>
37 #include <class_pcb_screen.h>
38 #include <confirm.h>
39 #include <kicad_string.h>
40 #include <richio.h>
41 #include <macros.h>
42 #include <math_for_graphics.h>
43 #include <wxBasePcbFrame.h>
44 #include <msgpanel.h>
45 #include <base_units.h>
46 #include <bitmaps.h>
47 
48 #include <wxPcbStruct.h>
49 #include <class_board.h>
50 #include <class_module.h>
51 #include <class_edge_mod.h>
52 
53 #include <stdio.h>
54 
57 {
58  m_Shape = aShape;
59  m_Angle = 0;
60  m_Layer = F_SilkS;
61 }
62 
63 
65 {
66 }
67 
68 
70 {
71  MODULE* module = (MODULE*) m_Parent;
72 
73  if( module == NULL )
74  {
75  m_Start0 = m_Start;
76  m_End0 = m_End;
77  return;
78  }
79 
80  m_Start0 = m_Start - module->GetPosition();
81  m_End0 = m_End - module->GetPosition();
82  double angle = module->GetOrientation();
83  RotatePoint( &m_Start0.x, &m_Start0.y, -angle );
84  RotatePoint( &m_End0.x, &m_End0.y, -angle );
85 }
86 
87 
89 {
90  MODULE* module = (MODULE*) m_Parent;
91 
92  m_Start = m_Start0;
93  m_End = m_End0;
94 
95  if( module )
96  {
97  RotatePoint( &m_Start.x, &m_Start.y, module->GetOrientation() );
98  RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
99 
100  m_Start += module->GetPosition();
101  m_End += module->GetPosition();
102  }
103 }
104 
105 
106 void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
107  const wxPoint& offset )
108 {
109  int ux0, uy0, dx, dy, radius, StAngle, EndAngle;
110  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
111 
112  MODULE* module = (MODULE*) m_Parent;
113 
114  if( !module )
115  return;
116 
117  BOARD* brd = GetBoard( );
118 
119  if( brd->IsLayerVisible( m_Layer ) == false )
120  return;
121 
122 
123  auto frame = static_cast<PCB_BASE_FRAME*> ( panel->GetParent() );
124  auto color = frame->Settings().Colors().GetLayerColor( m_Layer );
125 
126  DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();
127 
128  if(( draw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay )
129  {
130  if( !IsOnLayer( curr_layer ) )
132  }
133 
134  ux0 = m_Start.x - offset.x;
135  uy0 = m_Start.y - offset.y;
136 
137  dx = m_End.x - offset.x;
138  dy = m_End.y - offset.y;
139 
140  GRSetDrawMode( DC, draw_mode );
141  bool filled = displ_opts ? displ_opts->m_DisplayModEdgeFill : FILLED;
142 
143  if( IsCopperLayer( m_Layer ) )
144  filled = displ_opts ? displ_opts->m_DisplayPcbTrackFill : FILLED;
145 
146  switch( m_Shape )
147  {
148  case S_SEGMENT:
149  if( filled )
150  GRLine( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
151  else
152  // SKETCH Mode
153  GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
154 
155  break;
156 
157  case S_CIRCLE:
158  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
159 
160  if( filled )
161  {
162  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color );
163  }
164  else // SKETCH Mode
165  {
166  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + (m_Width / 2), color );
167  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - (m_Width / 2), color );
168  }
169 
170  break;
171 
172  case S_ARC:
173  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
174  StAngle = ArcTangente( dy - uy0, dx - ux0 );
175  EndAngle = StAngle + m_Angle;
176 
177  if( !panel->GetPrintMirrored() )
178  {
179  if( StAngle > EndAngle )
180  std::swap( StAngle, EndAngle );
181  }
182  else // Mirrored mode: arc orientation is reversed
183  {
184  if( StAngle < EndAngle )
185  std::swap( StAngle, EndAngle );
186  }
187 
188  if( filled )
189  {
190  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle, radius, m_Width, color );
191  }
192  else // SKETCH Mode
193  {
194  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
195  radius + (m_Width / 2), color );
196  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
197  radius - (m_Width / 2), color );
198  }
199  break;
200 
201  case S_POLYGON:
202  {
203  // We must compute absolute coordinates from m_PolyPoints
204  // which are relative to module position, orientation 0
205  std::vector<wxPoint> points = m_PolyPoints;
206 
207  for( unsigned ii = 0; ii < points.size(); ii++ )
208  {
209  wxPoint& pt = points[ii];
210 
211  RotatePoint( &pt.x, &pt.y, module->GetOrientation() );
212  pt += module->GetPosition() - offset;
213  }
214 
215  GRPoly( panel->GetClipBox(), DC, points.size(), &points[0], true, m_Width, color, color );
216  }
217  break;
218 
219  default:
220  break;
221  }
222 }
223 
224 
225 // see class_edge_mod.h
226 void EDGE_MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
227 {
228  wxString msg;
229 
230  MODULE* module = (MODULE*) m_Parent;
231 
232  if( !module )
233  return;
234 
235  BOARD* board = (BOARD*) module->GetParent();
236 
237  if( !board )
238  return;
239 
240  aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), module->GetReference(), DARKCYAN ) );
241  aList.push_back( MSG_PANEL_ITEM( _( "Value" ), module->GetValue(), BLUE ) );
242  msg.Printf( wxT( "%8.8lX" ), module->GetTimeStamp() );
243  aList.push_back( MSG_PANEL_ITEM( _( "TimeStamp" ), msg, BROWN ) );
244  aList.push_back( MSG_PANEL_ITEM( _( "Footprint Layer" ),
245  module->GetLayerName(), RED ) );
246 
247  // append the features shared with the base class
249 }
250 
251 
252 
254 {
255  wxString text;
256  text.Printf( _( "Graphic (%s) on %s of %s" ),
257  GetChars( ShowShape( m_Shape ) ),
258  GetChars( GetLayerName() ),
259  GetChars( ((MODULE*) GetParent())->GetReference() ) );
260 
261  return text;
262 }
263 
264 
266 {
267  return show_mod_edge_xpm;
268 }
269 
270 
272 {
273  return new EDGE_MODULE( *this );
274 }
275 
276 
277 void EDGE_MODULE::Flip( const wxPoint& aCentre )
278 {
279  wxPoint pt;
280 
281  switch( GetShape() )
282  {
283  case S_ARC:
284  SetAngle( -GetAngle() );
285  //Fall through
286  default:
287  case S_SEGMENT:
288  pt = GetStart();
289  MIRROR( pt.y, aCentre.y );
290  SetStart( pt );
291 
292  pt = GetEnd();
293  MIRROR( pt.y, aCentre.y );
294  SetEnd( pt );
295 
296  MIRROR( m_Start0.y, 0 );
297  MIRROR( m_End0.y, 0 );
298  break;
299 
300  case S_POLYGON:
301  // polygon corners coordinates are always relative to the
302  // footprint position, orientation 0
303  for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
304  MIRROR( m_PolyPoints[ii].y, 0 );
305  }
306 
307  // DRAWSEGMENT items are not usually on copper layers, but
308  // it can happen in microwave apps.
309  // However, currently, only on Front or Back layers.
310  // So the copper layers count is not taken in account
311  SetLayer( FlipLayer( GetLayer() ) );
312 }
313 
314 
315 void EDGE_MODULE::Mirror( wxPoint aCentre, bool aMirrorAroundXAxis )
316 {
317  // Mirror an edge of the footprint. the layer is not modified
318  // This is a footprint shape modification.
319  switch( GetShape() )
320  {
321  case S_ARC:
322  SetAngle( -GetAngle() );
323  //Fall through
324  default:
325  case S_SEGMENT:
326  if( aMirrorAroundXAxis )
327  {
328  MIRROR( m_Start0.y, aCentre.y );
329  MIRROR( m_End0.y, aCentre.y );
330  }
331  else
332  {
333  MIRROR( m_Start0.x, aCentre.x );
334  MIRROR( m_End0.x, aCentre.x );
335  }
336  break;
337 
338  case S_POLYGON:
339  // polygon corners coordinates are always relative to the
340  // footprint position, orientation 0
341  for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
342  {
343  if( aMirrorAroundXAxis )
344  MIRROR( m_PolyPoints[ii].y, aCentre.y );
345  else
346  MIRROR( m_PolyPoints[ii].x, aCentre.x );
347  }
348  }
349 
350  SetDrawCoord();
351 }
352 
353 void EDGE_MODULE::Rotate( const wxPoint& aRotCentre, double aAngle )
354 {
355  // We should rotate the relative coordinates, but to avoid duplicate code,
356  // do the base class rotation of draw coordinates, which is acceptable
357  // because in module editor, m_Pos0 = m_Pos
358  DRAWSEGMENT::Rotate( aRotCentre, aAngle );
359 
360  // and now update the relative coordinates, which are
361  // the reference in most transforms.
362  SetLocalCoord();
363 }
364 
365 
366 void EDGE_MODULE::Move( const wxPoint& aMoveVector )
367 {
368  // Move an edge of the footprint.
369  // This is a footprint shape modification.
370  m_Start0 += aMoveVector;
371  m_End0 += aMoveVector;
372 
373  switch( GetShape() )
374  {
375  default:
376  break;
377 
378  case S_POLYGON:
379  // polygon corners coordinates are always relative to the
380  // footprint position, orientation 0
381  for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
382  m_PolyPoints[ii] += aMoveVector;
383  }
384 
385  SetDrawCoord();
386 }
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it'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:767
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:168
virtual void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
PNG memory record (file in memory).
Definition: bitmap_types.h:38
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:290
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.
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:352
Class BOARD to handle a board.
const wxPoint & GetPosition() const override
Definition: class_module.h:155
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:445
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:481
bool m_DisplayModEdgeFill
Definition: pcbstruct.h:69
const wxString & GetValue() const
Function GetValue.
Definition: class_module.h:447
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.
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:106
wxPoint m_End0
This file contains miscellaneous commonly used macros and functions.
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.
bool m_DisplayPcbTrackFill
Definition: pcbstruct.h:71
PCB_LAYER_ID
A quick note on layer IDs:
STROKE_T GetShape() const
wxPoint m_Start
Line start point or Circle and Arc center.
Classes used in Pcbnew, CvPcb and GerbView.
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:160
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
Base window classes and related definitions.
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:982
bool m_ContrastModeDisplay
Definition: pcbstruct.h:85
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:175
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 Flip(const wxPoint &aCentre) override
Flip entity relative to aCentre.
void SetStart(const wxPoint &aStart)
time_t GetTimeStamp() const
Definition: base_struct.h:204
Class DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
Definition: pcbstruct.h:62
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.
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
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:419
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:791
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:188
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
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)
wxPoint m_Start0
void * GetDisplayOptions()
Function GetDisplayOptions A way to pass info to draw functions.
Definition: draw_panel.cpp:182
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
std::vector< wxPoint > m_PolyPoints
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.
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
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