KiCad PCB EDA Suite
class_drawsegment.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) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
7  * Copyright (C) 1992-2017 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 <macros.h>
34 #include <wxstruct.h>
35 #include <gr_basic.h>
36 #include <bezier_curves.h>
37 #include <class_drawpanel.h>
38 #include <class_pcb_screen.h>
39 #include <trigo.h>
40 #include <msgpanel.h>
41 #include <bitmaps.h>
42 
43 #include <wxPcbStruct.h>
44 
45 #include <pcbnew.h>
46 
47 #include <class_board.h>
48 #include <class_module.h>
49 #include <class_drawsegment.h>
50 #include <base_units.h>
51 
52 
54  BOARD_ITEM( aParent, idtype )
55 {
56  m_Type = 0;
57  m_Angle = 0;
58  m_Flags = 0;
60  // Gives a decent pen size to draw shape:
61  m_Width = m_Shape == S_POLYGON ? 0 : Millimeter2iu( 0.15 );
62 }
63 
64 
66 {
67 }
68 
69 
70 void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle )
71 {
72  switch( m_Shape )
73  {
74  case S_ARC:
75  case S_SEGMENT:
76  case S_CIRCLE:
77  // these can all be done by just rotating the start and end points
78  RotatePoint( &m_Start, aRotCentre, aAngle);
79  RotatePoint( &m_End, aRotCentre, aAngle);
80  break;
81 
82  case S_POLYGON:
83  for( auto iter = m_Poly.Iterate(); iter; iter++ )
84  {
85  RotatePoint( *iter, VECTOR2I(aRotCentre), aAngle);
86  }
87  break;
88 
89  case S_CURVE:
90  RotatePoint( &m_Start, aRotCentre, aAngle);
91  RotatePoint( &m_End, aRotCentre, aAngle);
92 
93  for( unsigned int ii = 0; ii < m_BezierPoints.size(); ii++ )
94  {
95  RotatePoint( &m_BezierPoints[ii], aRotCentre, aAngle);
96  }
97  break;
98 
99  case S_RECT:
100  default:
101  // un-handled edge transform
102  wxASSERT_MSG( false, wxT( "DRAWSEGMENT::Rotate not implemented for "
103  + ShowShape( m_Shape ) ) );
104  break;
105  }
106 }
107 
108 void DRAWSEGMENT::Flip( const wxPoint& aCentre )
109 {
110  m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
111  m_End.y = aCentre.y - (m_End.y - aCentre.y);
112 
113  if( m_Shape == S_ARC )
114  m_Angle = -m_Angle;
115 
116  // DRAWSEGMENT items are not allowed on copper layers, so
117  // copper layers count is not taken in accoun in Flip transform
118  SetLayer( FlipLayer( GetLayer() ) );
119 }
120 
122 {
123  wxPoint c;
124 
125  switch( m_Shape )
126  {
127  case S_ARC:
128  case S_CIRCLE:
129  c = m_Start;
130  break;
131 
132  case S_SEGMENT:
133  // Midpoint of the line
134  c = ( GetStart() + GetEnd() ) / 2;
135  break;
136 
137  case S_POLYGON:
138  case S_RECT:
139  case S_CURVE:
140  c = GetBoundingBox().Centre();
141  break;
142 
143  default:
144  wxASSERT_MSG( false, "DRAWSEGMENT::GetCentre not implemented for shape"
145  + ShowShape( GetShape() ) );
146  break;
147  }
148 
149  return c;
150 }
151 
153 {
154  wxPoint endPoint; // start of arc
155 
156  switch( m_Shape )
157  {
158  case S_ARC:
159  // rotate the starting point of the arc, given by m_End, through the
160  // angle m_Angle to get the ending point of the arc.
161  // m_Start is the arc centre
162  endPoint = m_End; // m_End = start point of arc
163  RotatePoint( &endPoint, m_Start, -m_Angle );
164  break;
165 
166  default:
167  ;
168  }
169 
170  return endPoint; // after rotation, the end of the arc.
171 }
172 
174 {
175  // due to the Y axis orient atan2 needs - y value
176  double angleStart = ArcTangente( GetArcStart().y - GetCenter().y,
177  GetArcStart().x - GetCenter().x );
178 
179  // Normalize it to 0 ... 360 deg, to avoid discontinuity for angles near 180 deg
180  // because 180 deg and -180 are very near angles when ampping betewwen -180 ... 180 deg.
181  // and this is not easy to handle in calculations
182  NORMALIZE_ANGLE_POS( angleStart );
183 
184  return angleStart;
185 }
186 
187 
188 void DRAWSEGMENT::SetAngle( double aAngle )
189 {
190  // m_Angle must be >= -360 and <= +360 degrees
191  m_Angle = NormalizeAngle360Max( aAngle );
192 }
193 
194 
196 {
197  if( !m_Parent || m_Parent->Type() != PCB_MODULE_T )
198  return NULL;
199 
200  return (MODULE*) m_Parent;
201 }
202 
203 
204 void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE draw_mode,
205  const wxPoint& aOffset )
206 {
207  int ux0, uy0, dx, dy;
208  int l_trace;
209  int radius;
210 
211  PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
212 
213  BOARD * brd = GetBoard( );
214 
215  if( brd->IsLayerVisible( GetLayer() ) == false )
216  return;
217 
218  auto frame = static_cast<PCB_EDIT_FRAME*> ( panel->GetParent() );
219  auto color = frame->Settings().Colors().GetLayerColor( GetLayer() );
220 
221  auto displ_opts = (PCB_DISPLAY_OPTIONS*) panel->GetDisplayOptions();
222 
223  if( ( draw_mode & GR_ALLOW_HIGHCONTRAST ) && displ_opts && displ_opts->m_ContrastModeDisplay )
224  {
225  if( !IsOnLayer( curr_layer ) && !IsOnLayer( Edge_Cuts ) )
227  }
228 
229  GRSetDrawMode( DC, draw_mode );
230  l_trace = m_Width >> 1; // half trace width
231 
232  // Line start point or Circle and Arc center
233  ux0 = m_Start.x + aOffset.x;
234  uy0 = m_Start.y + aOffset.y;
235 
236  // Line end point or circle and arc start point
237  dx = m_End.x + aOffset.x;
238  dy = m_End.y + aOffset.y;
239 
240  bool filled = displ_opts ? displ_opts->m_DisplayDrawItemsFill : FILLED;
241 
242  if( m_Flags & FORCE_SKETCH )
243  filled = SKETCH;
244 
245  switch( m_Shape )
246  {
247  case S_CIRCLE:
248  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
249 
250  if( filled )
251  {
252  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius, m_Width, color );
253  }
254  else
255  {
256  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius - l_trace, color );
257  GRCircle( panel->GetClipBox(), DC, ux0, uy0, radius + l_trace, color );
258  }
259 
260  break;
261 
262  case S_ARC:
263  double StAngle, EndAngle;
264  radius = KiROUND( Distance( ux0, uy0, dx, dy ) );
265  StAngle = ArcTangente( dy - uy0, dx - ux0 );
266  EndAngle = StAngle + m_Angle;
267 
268  if( !panel->GetPrintMirrored() )
269  {
270  if( StAngle > EndAngle )
271  std::swap( StAngle, EndAngle );
272  }
273  else // Mirrored mode: arc orientation is reversed
274  {
275  if( StAngle < EndAngle )
276  std::swap( StAngle, EndAngle );
277  }
278 
279  if( filled )
280  {
281  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
282  radius, m_Width, color );
283  }
284  else
285  {
286  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
287  radius - l_trace, color );
288  GRArc( panel->GetClipBox(), DC, ux0, uy0, StAngle, EndAngle,
289  radius + l_trace, color );
290  }
291 
292  break;
293 
294  case S_CURVE:
295  {
296  std::vector<wxPoint> ctrlPoints = { m_Start, m_BezierC1, m_BezierC2, m_End };
297  BEZIER_POLY converter( ctrlPoints );
298  converter.GetPoly( m_BezierPoints );
299  }
300 
301  for( unsigned int i=1; i < m_BezierPoints.size(); i++ )
302  {
303  if( filled )
304  {
305  GRFillCSegm( panel->GetClipBox(), DC,
306  m_BezierPoints[i].x, m_BezierPoints[i].y,
307  m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
308  m_Width, color );
309  }
310  else
311  {
312  GRCSegm( panel->GetClipBox(), DC,
313  m_BezierPoints[i].x, m_BezierPoints[i].y,
314  m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
315  m_Width, color );
316  }
317  }
318 
319  break;
320 
321  case S_POLYGON:
322  {
323  SHAPE_POLY_SET& outline = GetPolyShape();
324  // Draw the polygon: only one polygon is expected
325  // However we provide a multi polygon shape drawing
326  // ( for the future or to show a non expected shape )
327  for( int jj = 0; jj < outline.OutlineCount(); ++jj )
328  {
329  SHAPE_LINE_CHAIN& poly = outline.Outline( jj );
330 
331  GRClosedPoly( panel->GetClipBox(), DC, poly.PointCount(),
332  (wxPoint*)&poly.Point( 0 ), FILLED, GetWidth(),
333  color, color );
334  }
335  }
336  break;
337 
338  default:
339  if( filled )
340  {
341  GRFillCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
342  }
343  else
344  {
345  GRCSegm( panel->GetClipBox(), DC, ux0, uy0, dx, dy, m_Width, color );
346  }
347 
348  break;
349  }
350 }
351 
352 void DRAWSEGMENT::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
353 {
354  wxString msg;
355  wxASSERT( m_Parent );
356 
357  msg = _( "Drawing" );
358 
359  aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
360 
361  wxString shape = _( "Shape" );
362 
363  switch( m_Shape )
364  {
365  case S_CIRCLE:
366  aList.push_back( MSG_PANEL_ITEM( shape, _( "Circle" ), RED ) );
367  break;
368 
369  case S_ARC:
370  aList.push_back( MSG_PANEL_ITEM( shape, _( "Arc" ), RED ) );
371  msg.Printf( wxT( "%.1f" ), m_Angle / 10.0 );
372  aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, RED ) );
373  break;
374 
375  case S_CURVE:
376  aList.push_back( MSG_PANEL_ITEM( shape, _( "Curve" ), RED ) );
377  break;
378 
379  default:
380  {
381  aList.push_back( MSG_PANEL_ITEM( shape, _( "Segment" ), RED ) );
382 
384  aList.push_back( MSG_PANEL_ITEM( _( "Length" ), msg, DARKGREEN ) );
385 
386  // angle counter-clockwise from 3'o-clock
387  const double deg = RAD2DEG( atan2( (double)( m_Start.y - m_End.y ),
388  (double)( m_End.x - m_Start.x ) ) );
389  msg.Printf( wxT( "%.1f" ), deg );
390  aList.push_back( MSG_PANEL_ITEM( _( "Angle" ), msg, DARKGREEN ) );
391  }
392  }
393 
394  wxString start;
395  start << GetStart();
396 
397  wxString end;
398  end << GetEnd();
399 
400  aList.push_back( MSG_PANEL_ITEM( start, end, DARKGREEN ) );
401  aList.push_back( MSG_PANEL_ITEM( _( "Layer" ), GetLayerName(), DARKBROWN ) );
402  msg = ::CoordinateToString( m_Width );
403  aList.push_back( MSG_PANEL_ITEM( _( "Width" ), msg, DARKCYAN ) );
404 }
405 
406 
408 {
409  EDA_RECT bbox;
410 
411  bbox.SetOrigin( m_Start );
412 
413  switch( m_Shape )
414  {
415  case S_SEGMENT:
416  bbox.SetEnd( m_End );
417  break;
418 
419  case S_CIRCLE:
420  bbox.Inflate( GetRadius() );
421  break;
422 
423  case S_ARC:
424  computeArcBBox( bbox );
425  break;
426 
427  case S_POLYGON:
428  if( m_Poly.IsEmpty() )
429  break;
430  {
431  wxPoint p_end;
432  MODULE* module = GetParentModule();
433  bool first = true;
434 
435  for( auto iter = m_Poly.CIterate(); iter; iter++ )
436  {
437  wxPoint pt ( iter->x, iter->y );
438 
439  if( module ) // Transform, if we belong to a module
440  {
441  RotatePoint( &pt, module->GetOrientation() );
442  pt += module->GetPosition();
443  }
444 
445 
446  if( first )
447  {
448  p_end = pt;
449  bbox.SetX( pt.x );
450  bbox.SetY( pt.y );
451  first = false;
452  }
453  else
454  {
455 
456  bbox.SetX( std::min( bbox.GetX(), pt.x ) );
457  bbox.SetY( std::min( bbox.GetY(), pt.y ) );
458 
459  p_end.x = std::max( p_end.x, pt.x );
460  p_end.y = std::max( p_end.y, pt.y );
461  }
462  }
463 
464  bbox.SetEnd( p_end );
465  break;
466  }
467  default:
468  break;
469  }
470 
471  bbox.Inflate( ((m_Width+1) / 2) + 1 );
472  bbox.Normalize();
473 
474  return bbox;
475 }
476 
477 
478 bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) const
479 {
480  switch( m_Shape )
481  {
482  case S_CIRCLE:
483  case S_ARC:
484  {
485  wxPoint relPos = aPosition - GetCenter();
486  int radius = GetRadius();
487  int dist = KiROUND( EuclideanNorm( relPos ) );
488 
489  if( abs( radius - dist ) <= ( m_Width / 2 ) )
490  {
491  if( m_Shape == S_CIRCLE )
492  return true;
493 
494  // For arcs, the test point angle must be >= arc angle start
495  // and <= arc angle end
496  // However angle values > 360 deg are not easy to handle
497  // so we calculate the relative angle between arc start point and teast point
498  // this relative arc should be < arc angle if arc angle > 0 (CW arc)
499  // and > arc angle if arc angle < 0 (CCW arc)
500  double arc_angle_start = GetArcAngleStart(); // Always 0.0 ... 360 deg, in 0.1 deg
501 
502  double arc_hittest = ArcTangente( relPos.y, relPos.x );
503 
504  // Calculate relative angle between the starting point of the arc, and the test point
505  arc_hittest -= arc_angle_start;
506 
507  // Normalise arc_hittest between 0 ... 360 deg
508  NORMALIZE_ANGLE_POS( arc_hittest );
509 
510  // Check angle: inside the arc angle when it is > 0
511  // and outside the not drawn arc when it is < 0
512  if( GetAngle() >= 0.0 )
513  {
514  if( arc_hittest <= GetAngle() )
515  return true;
516  }
517  else
518  {
519  if( arc_hittest >= (3600.0 + GetAngle()) )
520  return true;
521  }
522  }
523  }
524  break;
525 
526  case S_CURVE:
527  for( unsigned int i= 1; i < m_BezierPoints.size(); i++)
528  {
529  if( TestSegmentHit( aPosition, m_BezierPoints[i-1], m_BezierPoints[i-1], m_Width / 2 ) )
530  return true;
531  }
532  break;
533 
534  case S_SEGMENT:
535  if( TestSegmentHit( aPosition, m_Start, m_End, m_Width / 2 ) )
536  return true;
537  break;
538 
539  case S_POLYGON: // not yet handled
540  {
541  #define MAX_DIST_IN_MM 0.25
542  int distmax = Millimeter2iu( 0.25 );
544  auto poly = m_Poly;
545 
546  if( poly.CollideVertex( VECTOR2I( aPosition ), dummy, distmax ) )
547  return true;
548 
549  if( poly.CollideEdge( VECTOR2I( aPosition ), dummy, distmax ) )
550  return true;
551  }
552  break;
553 
554  default:
555  wxASSERT_MSG( 0, wxString::Format( "unknown DRAWSEGMENT shape: %d", m_Shape ) );
556  break;
557  }
558 
559  return false;
560 }
561 
562 
563 bool DRAWSEGMENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
564 {
565  EDA_RECT arect = aRect;
566  arect.Normalize();
567  arect.Inflate( aAccuracy );
568 
569  EDA_RECT arcRect;
570  EDA_RECT bb = GetBoundingBox();
571 
572  switch( m_Shape )
573  {
574  case S_CIRCLE:
575  // Test if area intersects or contains the circle:
576  if( aContained )
577  return arect.Contains( bb );
578  else
579  {
580  // If the rectangle does not intersect the bounding box, this is a much quicker test
581  if( !aRect.Intersects( bb ) )
582  {
583  return false;
584  }
585  else
586  {
587  return arect.IntersectsCircleEdge( GetCenter(), GetRadius(), GetWidth() );
588  }
589 
590  }
591  break;
592 
593  case S_ARC:
594 
595  // Test for full containment of this arc in the rect
596  if( aContained )
597  {
598  return arect.Contains( bb );
599  }
600  // Test if the rect crosses the arc
601  else
602  {
603  arcRect = bb.Common( arect );
604 
605  /* All following tests must pass:
606  * 1. Rectangle must intersect arc BoundingBox
607  * 2. Rectangle must cross the outside of the arc
608  */
609  return arcRect.Intersects( arect ) &&
611  }
612  break;
613  case S_SEGMENT:
614  if( aContained )
615  {
616  return arect.Contains( GetStart() ) && aRect.Contains( GetEnd() );
617  }
618  else
619  {
620  // Account for the width of the line
621  arect.Inflate( GetWidth() / 2 );
622  return arect.Intersects( GetStart(), GetEnd() );
623  }
624 
625  break;
626 
627  case S_CURVE:
628  case S_POLYGON: // not yet handled
629  break;
630 
631  default:
632  wxASSERT_MSG( 0, wxString::Format( "unknown DRAWSEGMENT shape: %d", m_Shape ) );
633  break;
634  }
635 
636  return false;
637 }
638 
639 
641 {
642  wxString text;
643  wxString temp = ::LengthDoubleToString( GetLength() );
644 
645  text.Printf( _( "Pcb Graphic: %s, length %s on %s" ),
646  GetChars( ShowShape( m_Shape ) ),
647  GetChars( temp ), GetChars( GetLayerName() ) );
648 
649  return text;
650 }
651 
652 
654 {
655  return add_dashed_line_xpm;
656 }
657 
658 
660 {
661  return new DRAWSEGMENT( *this );
662 }
663 
664 
666 {
667  // For arcs - do not include the center point in the bounding box,
668  // it is redundant for displaying an arc
669  if( m_Shape == S_ARC )
670  {
671  EDA_RECT bbox;
672  bbox.SetOrigin( m_End );
673  computeArcBBox( bbox );
674  return BOX2I( bbox.GetOrigin(), bbox.GetSize() );
675  }
676 
677  return EDA_ITEM::ViewBBox();
678 }
679 
680 
682 {
683  // Do not include the center, which is not necessarily
684  // inside the BB of a arc with a small angle
685  aBBox.SetOrigin( m_End );
686 
687  wxPoint end = m_End;
688  RotatePoint( &end, m_Start, -m_Angle );
689  aBBox.Merge( end );
690 
691  // Determine the starting quarter
692  // 0 right-bottom
693  // 1 left-bottom
694  // 2 left-top
695  // 3 right-top
696  unsigned int quarter = 0; // assume right-bottom
697 
698  if( m_End.x < m_Start.x )
699  {
700  if( m_End.y <= m_Start.y )
701  quarter = 2;
702  else // ( m_End.y > m_Start.y )
703  quarter = 1;
704  }
705  else if( m_End.x >= m_Start.x )
706  {
707  if( m_End.y < m_Start.y )
708  quarter = 3;
709  else if( m_End.x == m_Start.x )
710  quarter = 1;
711  }
712 
713  int radius = GetRadius();
714  int angle = (int) GetArcAngleStart() % 900 + m_Angle;
715  bool directionCW = ( m_Angle > 0 ); // Is the direction of arc clockwise?
716 
717  // Make the angle positive, so we go clockwise and merge points belonging to the arc
718  if( !directionCW )
719  {
720  angle = 900 - angle;
721  quarter = ( quarter + 3 ) % 4; // -1 modulo arithmetic
722  }
723 
724  while( angle > 900 )
725  {
726  switch( quarter )
727  {
728  case 0:
729  aBBox.Merge( wxPoint( m_Start.x, m_Start.y + radius ) ); // down
730  break;
731 
732  case 1:
733  aBBox.Merge( wxPoint( m_Start.x - radius, m_Start.y ) ); // left
734  break;
735 
736  case 2:
737  aBBox.Merge( wxPoint( m_Start.x, m_Start.y - radius ) ); // up
738  break;
739 
740  case 3:
741  aBBox.Merge( wxPoint( m_Start.x + radius, m_Start.y ) ); // right
742  break;
743  }
744 
745  if( directionCW )
746  ++quarter;
747  else
748  quarter += 3; // -1 modulo arithmetic
749 
750  quarter %= 4;
751  angle -= 900;
752  }
753 }
754 
755 void DRAWSEGMENT::SetPolyPoints( const std::vector<wxPoint>& aPoints )
756 {
758  m_Poly.NewOutline();
759 
760  for ( auto p : aPoints )
761  {
762  m_Poly.Append( p.x, p.y );
763  }
764 }
765 
766 const std::vector<wxPoint> DRAWSEGMENT::GetPolyPoints() const
767 {
768  std::vector<wxPoint> rv;
769 
770  if( !m_Poly.IsEmpty() )
771  {
772  for ( auto iter = m_Poly.CIterate(); iter; iter++ )
773  {
774  rv.push_back( wxPoint( iter->x, iter->y ) );
775  }
776  }
777 
778  return rv;
779 }
780 
782 {
783  assert( aImage->Type() == PCB_LINE_T );
784 
785  std::swap( *((DRAWSEGMENT*) this), *((DRAWSEGMENT*) aImage) );
786 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
wxString CoordinateToString(int aValue, bool aConvertToMils)
Function CoordinateToString is a helper to convert the integer coordinate aValue to a string in inche...
Definition: base_units.cpp:117
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
static wxString ShowShape(STROKE_T aShape)
Function ShowShape converts the enum STROKE_T integer value to a wxString.
virtual void Flip(const wxPoint &aCentre) override
Function Flip Flip this object, i.e.
BOX2< VECTOR2I > BOX2I
Definition: box2.h:468
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: base_struct.h:182
double GetLength() const
Function GetLength returns the length of the track using the hypotenuse calculation.
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Function GetLineLength returns the length of a line segment defined by aPointA and aPointB...
Definition: trigo.h:191
void Merge(const EDA_RECT &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect...
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:296
bool IntersectsCircleEdge(const wxPoint &aCenter, const int aRadius, const int aWidth) const
IntersectsCircleEdge Tests for intersection between this rect and the edge (radius) of a circle...
T NormalizeAngle360Max(T Angle)
Normalize angle to be >=-360.0 and <= 360.0 Angle can be equal to -360 or +360.
Definition: trigo.h:211
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:106
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...
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
const wxPoint GetCenter() const override
Function GetCenter()
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int PointCount() const
Function PointCount()
bool Contains(const wxPoint &aPoint) const
Function Contains.
Class BOARD to handle a board.
const wxPoint & GetPosition() const override
Definition: class_module.h:175
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:445
virtual BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
virtual bool HitTest(const wxPoint &aPosition) const override
Function HitTest tests if aPosition is contained within or on the bounding area of an item...
double RAD2DEG(double rad)
Definition: trigo.h:200
void GetPoly(std::vector< wxPoint > &aOutput)
Converts Bezier curve to a polygon.
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
double GetArcAngleStart() const
function GetArcAngleStart()
EDA_RECT Common(const EDA_RECT &aRect) const
Function Common returns the area that is common with another rectangle.
static const int dist[10][10]
Definition: dist.cpp:57
Struct VERTEX_INDEX.
void SetOrigin(const wxPoint &pos)
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:488
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...
int OutlineCount() const
Returns the number of outlines in the set
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:241
VECTOR2< int > VECTOR2I
Definition: vector2d.h:589
const std::vector< wxPoint > GetPolyPoints() const
#define abs(a)
Definition: auxiliary.h:84
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
void GRClosedPoly(EDA_RECT *ClipBox, wxDC *DC, int n, wxPoint Points[], bool Fill, COLOR4D Color, COLOR4D BgColor)
Function GRClosedPoly draws a closed polygon onto the drawing context aDC and optionally fills and/or...
Definition: gr_basic.cpp:784
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
This file contains miscellaneous commonly used macros and functions.
wxPoint m_BezierC1
Bezier Control Point 1.
const wxPoint & GetArcStart() const
const wxPoint & GetOrigin() const
segment with non rounded ends
class MODULE, a footprint
Definition: typeinfo.h:89
virtual EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
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
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:41
Class SHAPE_POLY_SET.
Base window classes and related definitions.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
void GRFillCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:591
void SetEnd(int x, int y)
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:981
EDA_RECT * GetClipBox()
void SetX(int val)
wxString LengthDoubleToString(double aValue, bool aConvertToMils)
Function LengthDoubleToString is a helper to convert the double length aValue to a string in inches...
Definition: base_units.cpp:122
STROKE_T m_Shape
Shape: line, Circle, Arc.
Definition: colors.h:60
EDA_DRAW_FRAME * GetParent() const
Definition: draw_panel.cpp:174
SHAPE_POLY_SET & GetPolyShape()
Bezier Curve.
wxPoint Centre() const
void computeArcBBox(EDA_RECT &aBBox) const
int NewOutline()
Creates a new empty polygon in the set and returns its index
void SetY(int val)
void SetPolyPoints(const std::vector< wxPoint > &aPoints)
void Normalize()
Function Normalize ensures that the height ant width are positive.
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
Bezier curves to polygon converter.
Definition: bezier_curves.h:34
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
int m_Type
Used in complex associations ( Dimensions.. )
Class to handle a graphic segment.
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
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
#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
Class SHAPE_LINE_CHAIN.
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:828
STATUS_FLAGS m_Flags
Flag bits for editing and other uses.
Definition: base_struct.h:189
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
const wxPoint GetArcEnd() const
Class EDA_RECT handles the component boundary box.
int GetX() const
wxPoint m_BezierC2
Bezier Control Point 2.
BASE_SCREEN * GetScreen()
Definition: draw_panel.cpp:187
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:165
int GetWidth() const
int GetY() const
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
void SetAngle(double aAngle)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees...
MODULE * GetParentModule() const
Function GetParentModule returns a pointer to the parent module, or NULL if DRAWSEGMENT does not belo...
VECTOR2I & Point(int aIndex)
Function Point()
int m_Width
thickness of lines ...
Module description (excepted pads)
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
void * GetDisplayOptions()
Function GetDisplayOptions A way to pass info to draw functions.
Definition: draw_panel.cpp:181
DRAWSEGMENT(BOARD_ITEM *aParent=NULL, KICAD_T idtype=PCB_LINE_T)
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Function TestSegmentHit test for hit on line segment i.e.
Definition: trigo.cpp:142
double Distance(double x1, double y1, double x2, double y2)
void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset=ZeroOffset) override
Function Draw BOARD_ITEMs have their own color information.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
Message panel definition file.
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
#define FORCE_SKETCH
Definition: pcbnew.h:68
const wxSize & GetSize() const
virtual wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
#define min(a, b)
Definition: auxiliary.h:85
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
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline) ...
std::vector< wxPoint > m_BezierPoints
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
virtual const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...