KiCad PCB EDA Suite
board_items_to_polygon_shape_transform.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) 2009-2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <vector>
26 #include <bezier_curves.h>
27 #include <trigo.h>
28 #include <board.h>
29 #include <pad.h>
30 #include <dimension.h>
31 #include <track.h>
32 #include <kicad_string.h>
33 #include <pcb_shape.h>
34 #include <pcb_text.h>
35 #include <zone.h>
36 #include <footprint.h>
37 #include <fp_shape.h>
40 #include <geometry/shape_segment.h>
41 #include <geometry/shape_circle.h>
42 #include <geometry/shape_rect.h>
44 
45 
46 // A helper struct for the callback function
47 // These variables are parameters used in addTextSegmToPoly.
48 // But addTextSegmToPoly is a call-back function,
49 // so we cannot send them as arguments.
51 {
53  int m_error;
55 };
56 
58 
59 
60 // This is a call back function, used by GRText to draw the 3D text shape:
61 static void addTextSegmToPoly( int x0, int y0, int xf, int yf, void* aData )
62 {
63  TSEGM_2_POLY_PRMS* prm = static_cast<TSEGM_2_POLY_PRMS*>( aData );
64  TransformOvalToPolygon( *prm->m_cornerBuffer, wxPoint( x0, y0 ), wxPoint( xf, yf ),
65  prm->m_textWidth, prm->m_error, ERROR_INSIDE );
66 }
67 
68 
70 {
71  int maxError = GetDesignSettings().m_MaxError;
72 
73  // convert tracks and vias:
74  for( const TRACK* track : m_tracks )
75  {
76  if( !track->IsOnLayer( aLayer ) )
77  continue;
78 
79  track->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
80  ERROR_INSIDE );
81  }
82 
83  // convert pads and other copper items in footprints
84  for( const FOOTPRINT* footprint : m_footprints )
85  {
86  footprint->TransformPadsWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
87  ERROR_INSIDE );
88 
89  // Micro-wave footprints may have items on copper layers
90  footprint->TransformFPShapesWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
92  true, /* include text */
93  true /* include shapes */ );
94 
95  for( const ZONE* zone : footprint->Zones() )
96  {
97  if( zone->GetLayerSet().test( aLayer ) )
98  zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
99  }
100  }
101 
102  // convert copper zones
103  for( const ZONE* zone : Zones() )
104  {
105  if( zone->GetLayerSet().test( aLayer ) )
106  zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
107  }
108 
109  // convert graphic items on copper layers (texts)
110  for( const BOARD_ITEM* item : m_drawings )
111  {
112  if( !item->IsOnLayer( aLayer ) )
113  continue;
114 
115  switch( item->Type() )
116  {
117  case PCB_SHAPE_T:
118  {
119  const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( item );
120  shape->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
121  ERROR_INSIDE );
122  }
123  break;
124 
125  case PCB_TEXT_T:
126  {
127  const PCB_TEXT* text = static_cast<const PCB_TEXT*>( item );
128  text->TransformTextShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
129  ERROR_INSIDE );
130  }
131  break;
132 
133  default:
134  break;
135  }
136  }
137 }
138 
139 
141  PCB_LAYER_ID aLayer, int aClearance,
142  int aMaxError, ERROR_LOC aErrorLoc,
143  bool aSkipNPTHPadsWihNoCopper,
144  bool aSkipPlatedPads,
145  bool aSkipNonPlatedPads ) const
146 {
147  for( const PAD* pad : m_pads )
148  {
149  if( aLayer != UNDEFINED_LAYER && !pad->IsOnLayer(aLayer) )
150  continue;
151 
152  if( !pad->FlashLayer( aLayer ) && IsCopperLayer( aLayer ) )
153  continue;
154 
155  // NPTH pads are not drawn on layers if the shape size and pos is the same
156  // as their hole:
157  if( aSkipNPTHPadsWihNoCopper && pad->GetAttribute() == PAD_ATTRIB::NPTH )
158  {
159  if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
160  {
161  switch( pad->GetShape() )
162  {
163  case PAD_SHAPE::CIRCLE:
164  if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
165  continue;
166  break;
167 
168  case PAD_SHAPE::OVAL:
169  if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
170  continue;
171  break;
172 
173  default:
174  break;
175  }
176  }
177  }
178 
179  const bool isPlated = ( ( aLayer == F_Cu ) && pad->FlashLayer( F_Mask ) ) ||
180  ( ( aLayer == B_Cu ) && pad->FlashLayer( B_Mask ) );
181 
182  if( aSkipPlatedPads && isPlated )
183  continue;
184 
185  if( aSkipNonPlatedPads && !isPlated )
186  continue;
187 
188  wxSize clearance( aClearance, aClearance );
189 
190  switch( aLayer )
191  {
192  case F_Mask:
193  case B_Mask:
194  clearance.x += pad->GetSolderMaskMargin();
195  clearance.y += pad->GetSolderMaskMargin();
196  break;
197 
198  case F_Paste:
199  case B_Paste:
200  clearance += pad->GetSolderPasteMargin();
201  break;
202 
203  default:
204  break;
205  }
206 
207  // Our standard TransformShapeWithClearanceToPolygon() routines can't handle differing
208  // x:y clearance values (which get generated when a relative paste margin is used with
209  // an oblong pad). So we apply this huge hack and fake a larger pad to run the transform
210  // on.
211  // Of course being a hack it falls down when dealing with custom shape pads (where the
212  // size is only the size of the anchor), so for those we punt and just use clearance.x.
213 
214  if( ( clearance.x < 0 || clearance.x != clearance.y )
215  && pad->GetShape() != PAD_SHAPE::CUSTOM )
216  {
217  PAD dummy( *pad );
218  dummy.SetSize( pad->GetSize() + clearance + clearance );
219  dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0,
220  aMaxError, aErrorLoc );
221  }
222  else
223  {
224  pad->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, clearance.x,
225  aMaxError, aErrorLoc );
226  }
227  }
228 }
229 
239  PCB_LAYER_ID aLayer, int aClearance,
240  int aError, ERROR_LOC aErrorLoc,
241  bool aIncludeText,
242  bool aIncludeShapes ) const
243 {
244  std::vector<FP_TEXT*> texts; // List of FP_TEXT to convert
245 
246  for( BOARD_ITEM* item : GraphicalItems() )
247  {
248  if( item->Type() == PCB_FP_TEXT_T && aIncludeText )
249  {
250  FP_TEXT* text = static_cast<FP_TEXT*>( item );
251 
252  if( aLayer != UNDEFINED_LAYER && text->GetLayer() == aLayer && text->IsVisible() )
253  texts.push_back( text );
254  }
255 
256  if( item->Type() == PCB_FP_SHAPE_T && aIncludeShapes )
257  {
258  const FP_SHAPE* outline = static_cast<FP_SHAPE*>( item );
259 
260  if( aLayer != UNDEFINED_LAYER && outline->GetLayer() == aLayer )
261  {
262  outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0,
263  aError, aErrorLoc );
264  }
265  }
266  }
267 
268  if( aIncludeText )
269  {
270  if( Reference().GetLayer() == aLayer && Reference().IsVisible() )
271  texts.push_back( &Reference() );
272 
273  if( Value().GetLayer() == aLayer && Value().IsVisible() )
274  texts.push_back( &Value() );
275  }
276 
277  for( const FP_TEXT* text : texts )
278  {
279  text->TransformTextShapeWithClearanceToPolygon( aCornerBuffer, aLayer, aClearance,
280  aError, aErrorLoc );
281  }
282 }
283 
284 
292  PCB_LAYER_ID aLayer, int aClearance,
293  int aError, ERROR_LOC aErrorLoc ) const
294 {
295  prms.m_cornerBuffer = &aCornerBuffer;
296  prms.m_textWidth = GetEffectiveTextPenWidth() + ( 2 * aClearance );
297  prms.m_error = aError;
298  wxSize size = GetTextSize();
299  int penWidth = GetEffectiveTextPenWidth();
300 
301  if( IsMirrored() )
302  size.x = -size.x;
303 
305  GetVertJustify(), penWidth, IsItalic(), IsBold(), addTextSegmToPoly, &prms );
306 }
307 
308 
310  PCB_LAYER_ID aLayer, int aClearance,
311  int aError, ERROR_LOC aErrorLoc,
312  bool aIgnoreLineWidth ) const
313 {
314  EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( &aCornerBuffer, aClearance );
315 }
316 
317 
319  int aError ) const
320 {
321  if( !m_FilledPolysList.count( aLayer ) || m_FilledPolysList.at( aLayer ).IsEmpty() )
322  return;
323 
324  // Just add filled areas if filled polygons outlines have no thickness
326  {
327  const SHAPE_POLY_SET& polys = m_FilledPolysList.at( aLayer );
328  aCornerBuffer.Append( polys );
329  return;
330  }
331 
332  // Filled areas have polygons with outline thickness.
333  // we must create the polygons and add inflated polys
334  SHAPE_POLY_SET polys = m_FilledPolysList.at( aLayer );
335 
336  auto board = GetBoard();
337  int maxError = ARC_HIGH_DEF;
338 
339  if( board )
340  maxError = board->GetDesignSettings().m_MaxError;
341 
342  int numSegs = GetArcToSegmentCount( GetMinThickness(), maxError, 360.0 );
343 
345 
346  aCornerBuffer.Append( polys );
347 }
348 
349 
351  int aClearanceValue ) const
352 {
353  if( GetText().Length() == 0 )
354  return;
355 
356  wxPoint corners[4]; // Buffer of polygon corners
357 
358  EDA_RECT rect = GetTextBox();
359  rect.Inflate( aClearanceValue + Millimeter2iu( DEFAULT_TEXT_WIDTH ) );
360  corners[0].x = rect.GetOrigin().x;
361  corners[0].y = rect.GetOrigin().y;
362  corners[1].y = corners[0].y;
363  corners[1].x = rect.GetRight();
364  corners[2].x = corners[1].x;
365  corners[2].y = rect.GetBottom();
366  corners[3].y = corners[2].y;
367  corners[3].x = corners[0].x;
368 
369  aCornerBuffer->NewOutline();
370 
371  for( wxPoint& corner : corners )
372  {
373  // Rotate polygon
374  RotatePoint( &corner.x, &corner.y, GetTextPos().x, GetTextPos().y, GetTextAngle() );
375  aCornerBuffer->Append( corner.x, corner.y );
376  }
377 }
378 
379 
387  PCB_LAYER_ID aLayer, int aClearanceValue,
388  int aError, ERROR_LOC aErrorLoc ) const
389 {
390  wxSize size = GetTextSize();
391 
392  if( IsMirrored() )
393  size.x = -size.x;
394 
395  int penWidth = GetEffectiveTextPenWidth();
396 
397  prms.m_cornerBuffer = &aCornerBuffer;
398  prms.m_textWidth = GetEffectiveTextPenWidth() + ( 2 * aClearanceValue );
399  prms.m_error = aError;
400  COLOR4D color; // not actually used, but needed by GRText
401 
403  GetVertJustify(), penWidth, IsItalic(), IsBold(), addTextSegmToPoly, &prms );
404 }
405 
406 
408  PCB_LAYER_ID aLayer, int aClearance,
409  int aError, ERROR_LOC aErrorLoc,
410  bool aIgnoreLineWidth ) const
411 {
412  EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( &aCornerBuffer, aClearance );
413 }
414 
415 
417  PCB_LAYER_ID aLayer, int aClearanceValue,
418  int aError, ERROR_LOC aErrorLoc,
419  bool ignoreLineWidth ) const
420 {
421  int width = ignoreLineWidth ? 0 : m_width;
422 
423  width += 2 * aClearanceValue;
424 
425  switch( m_shape )
426  {
428  if( IsFilled() )
429  {
430  TransformCircleToPolygon( aCornerBuffer, GetCenter(), GetRadius() + width / 2, aError,
431  aErrorLoc );
432  }
433  else
434  {
435  TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius(), width, aError,
436  aErrorLoc );
437  }
438  break;
439 
441  {
442  std::vector<wxPoint> pts = GetRectCorners();
443 
444  if( IsFilled() )
445  {
446  aCornerBuffer.NewOutline();
447 
448  for( const wxPoint& pt : pts )
449  aCornerBuffer.Append( pt );
450  }
451 
452  if( width > 0 || !IsFilled() )
453  {
454  // Add in segments
455  TransformOvalToPolygon( aCornerBuffer, pts[0], pts[1], width, aError, aErrorLoc );
456  TransformOvalToPolygon( aCornerBuffer, pts[1], pts[2], width, aError, aErrorLoc );
457  TransformOvalToPolygon( aCornerBuffer, pts[2], pts[3], width, aError, aErrorLoc );
458  TransformOvalToPolygon( aCornerBuffer, pts[3], pts[0], width, aError, aErrorLoc );
459  }
460  }
461  break;
462 
463  case PCB_SHAPE_TYPE::ARC:
464  TransformArcToPolygon( aCornerBuffer, GetArcStart(), GetArcMid(), GetArcEnd(), width,
465  aError, aErrorLoc );
466  break;
467 
469  TransformOvalToPolygon( aCornerBuffer, m_start, m_end, width, aError, aErrorLoc );
470  break;
471 
473  {
474  if( !IsPolyShapeValid() )
475  break;
476 
477  // The polygon is expected to be a simple polygon; not self intersecting, no hole.
478  FOOTPRINT* footprint = GetParentFootprint();
479  double orientation = footprint ? footprint->GetOrientation() : 0.0;
480  wxPoint offset;
481 
482  if( footprint )
483  offset = footprint->GetPosition();
484 
485  // Build the polygon with the actual position and orientation:
486  std::vector<wxPoint> poly;
487  poly = BuildPolyPointsList();
488 
489  for( wxPoint& point : poly )
490  {
491  RotatePoint( &point, orientation );
492  point += offset;
493  }
494 
495  if( IsFilled() )
496  {
497  aCornerBuffer.NewOutline();
498 
499  for( const wxPoint& point : poly )
500  aCornerBuffer.Append( point.x, point.y );
501  }
502 
503  if( width > 0 || !IsFilled() )
504  {
505  wxPoint pt1( poly[ poly.size() - 1] );
506 
507  for( const wxPoint& pt2 : poly )
508  {
509  if( pt2 != pt1 )
510  TransformOvalToPolygon( aCornerBuffer, pt1, pt2, width, aError, aErrorLoc );
511 
512  pt1 = pt2;
513  }
514  }
515  }
516  break;
517 
518  case PCB_SHAPE_TYPE::CURVE: // Bezier curve
519  {
520  std::vector<wxPoint> ctrlPoints = { m_start, m_bezierC1, m_bezierC2, m_end };
521  BEZIER_POLY converter( ctrlPoints );
522  std::vector< wxPoint> poly;
523  converter.GetPoly( poly, m_width );
524 
525  for( unsigned ii = 1; ii < poly.size(); ii++ )
526  {
527  TransformOvalToPolygon( aCornerBuffer, poly[ii - 1], poly[ii], width, aError, aErrorLoc );
528  }
529  }
530  break;
531 
532  default:
533  wxFAIL_MSG( "PCB_SHAPE::TransformShapeWithClearanceToPolygon no implementation for "
535  break;
536  }
537 }
538 
539 
541  PCB_LAYER_ID aLayer, int aClearanceValue,
542  int aError, ERROR_LOC aErrorLoc,
543  bool ignoreLineWidth ) const
544 {
545  wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for tracks." );
546 
547 
548  switch( Type() )
549  {
550  case PCB_VIA_T:
551  {
552  int radius = ( m_Width / 2 ) + aClearanceValue;
553  TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aError, aErrorLoc );
554  }
555  break;
556 
557  case PCB_ARC_T:
558  {
559  const ARC* arc = static_cast<const ARC*>( this );
560  int width = m_Width + ( 2 * aClearanceValue );
561 
562  TransformArcToPolygon( aCornerBuffer, arc->GetStart(), arc->GetMid(),
563  arc->GetEnd(), width, aError, aErrorLoc );
564  }
565  break;
566 
567  default:
568  {
569  int width = m_Width + ( 2 * aClearanceValue );
570 
571  TransformOvalToPolygon( aCornerBuffer, m_Start, m_End, width, aError, aErrorLoc );
572  }
573  break;
574  }
575 }
576 
577 
579  PCB_LAYER_ID aLayer, int aClearanceValue,
580  int aError, ERROR_LOC aErrorLoc,
581  bool ignoreLineWidth ) const
582 {
583  wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for pads." );
584 
585  // minimal segment count to approximate a circle to create the polygonal pad shape
586  // This minimal value is mainly for very small pads, like SM0402.
587  // Most of time pads are using the segment count given by aError value.
588  const int pad_min_seg_per_circle_count = 16;
589  double angle = m_orient;
590  int dx = m_size.x / 2;
591  int dy = m_size.y / 2;
592 
593  wxPoint padShapePos = ShapePos(); // Note: for pad having a shape offset,
594  // the pad position is NOT the shape position
595 
596  switch( GetShape() )
597  {
598  case PAD_SHAPE::CIRCLE:
599  case PAD_SHAPE::OVAL:
600  if( dx == dy )
601  {
602  TransformCircleToPolygon( aCornerBuffer, padShapePos, dx + aClearanceValue, aError,
603  aErrorLoc );
604  }
605  else
606  {
607  int half_width = std::min( dx, dy );
608  wxPoint delta( dx - half_width, dy - half_width );
609 
610  RotatePoint( &delta, angle );
611 
612  TransformOvalToPolygon( aCornerBuffer, padShapePos - delta, padShapePos + delta,
613  ( half_width + aClearanceValue ) * 2, aError, aErrorLoc );
614  }
615 
616  break;
617 
619  case PAD_SHAPE::RECT:
620  {
621  int ddx = GetShape() == PAD_SHAPE::TRAPEZOID ? m_deltaSize.x / 2 : 0;
622  int ddy = GetShape() == PAD_SHAPE::TRAPEZOID ? m_deltaSize.y / 2 : 0;
623 
624  wxPoint corners[4];
625  corners[0] = wxPoint( -dx - ddy, dy + ddx );
626  corners[1] = wxPoint( dx + ddy, dy - ddx );
627  corners[2] = wxPoint( dx - ddy, -dy + ddx );
628  corners[3] = wxPoint( -dx + ddy, -dy - ddx );
629 
630  SHAPE_POLY_SET outline;
631  outline.NewOutline();
632 
633  for( wxPoint& corner : corners )
634  {
635  RotatePoint( &corner, angle );
636  corner += padShapePos;
637  outline.Append( corner.x, corner.y );
638  }
639 
640  if( aClearanceValue )
641  {
642  int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ),
643  pad_min_seg_per_circle_count );
644  int clearance = aClearanceValue;
645 
646  if( aErrorLoc == ERROR_OUTSIDE )
647  clearance += GetCircleToPolyCorrection( aError );
648 
649  outline.Inflate( clearance, numSegs );
650  }
651 
652  aCornerBuffer.Append( outline );
653  }
654  break;
655 
658  {
659  int radius = GetRoundRectCornerRadius();
660  wxSize shapesize( m_size );
661  bool doChamfer = GetShape() == PAD_SHAPE::CHAMFERED_RECT;
662 
663  double chamferRatio = doChamfer ? GetChamferRectRatio() : 0.0;
664 
665  if( aClearanceValue )
666  {
667  radius += aClearanceValue;
668  shapesize.x += aClearanceValue * 2;
669  shapesize.y += aClearanceValue * 2;
670 
671  // The chamfer position (the 45 deg line on corner) must be
672  // offsetted by aClearanceValue from the base shape chamfer pos
673  // So we recalculate the chamferRatio to do that
674  //
675  // the chamfered shape is square with widet = w, and a corner dist from center
676  // is w*1.414 / 2 = w*0.707
677  // the distance from corner to chamfer line is ch = chamfer_size/707
678  // the distance from center to chamfer line is
679  // d = w*707 - ch/707
680  // so we have:
681  // base shape: d1 = w1*707 - ch1/707 = 0.707 * ( w1 - w1*chamferRatio)
682  // shape with clearance: d2 = w2*707 - ch2/707 = d1 + aClearanceValue
683  const double rootsq_2 = 1.41421356237/2;
684  int d1 = rootsq_2 * std::min( m_size.x, m_size.y ) * ( 1 - GetChamferRectRatio() );
685  int d2 = d1 + aClearanceValue;
686  // d2 = 0.707 * w2 * ( 1 - chamferRatio2 )
687  // 1 - d2 / ( 0.707 * w2 ) = chamferRatio2
688  chamferRatio = 1.0 - d2 / ( rootsq_2 * std::min( shapesize.x, shapesize.y ) );
689 
690  // Ensure chamferRatio = 0.0 ... 0.5
691  if( chamferRatio < 0.0 )
692  chamferRatio = 0.0;
693 
694  if( chamferRatio > 0.5 )
695  chamferRatio = 0.5;
696  }
697 
698  SHAPE_POLY_SET outline;
699  TransformRoundChamferedRectToPolygon( outline, padShapePos, shapesize, angle, radius,
700  chamferRatio,
701  doChamfer ? GetChamferPositions() : 0,
702  aError, aErrorLoc );
703 
704  aCornerBuffer.Append( outline );
705  }
706  break;
707 
708  case PAD_SHAPE::CUSTOM:
709  {
710  SHAPE_POLY_SET outline;
711  MergePrimitivesAsPolygon( &outline, aLayer, aErrorLoc );
712  outline.Rotate( -DECIDEG2RAD( m_orient ) );
713  outline.Move( VECTOR2I( m_pos ) );
714 
715  if( aClearanceValue )
716  {
717  int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ),
718  pad_min_seg_per_circle_count );
719  int clearance = aClearanceValue;
720 
721  if( aErrorLoc == ERROR_OUTSIDE )
722  clearance += GetCircleToPolyCorrection( aError );
723 
724  outline.Inflate( clearance, numSegs );
727  }
728 
729  aCornerBuffer.Append( outline );
730  }
731  break;
732 
733  default:
734  wxFAIL_MSG( "PAD::TransformShapeWithClearanceToPolygon no implementation for "
736  break;
737  }
738 }
739 
740 
741 
742 bool PAD::TransformHoleWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aInflateValue,
743  int aError, ERROR_LOC aErrorLoc ) const
744 {
745  wxSize drillsize = GetDrillSize();
746 
747  if( !drillsize.x || !drillsize.y )
748  return false;
749 
750  const SHAPE_SEGMENT* seg = GetEffectiveHoleShape();
751 
752  TransformOvalToPolygon( aCornerBuffer, (wxPoint) seg->GetSeg().A, (wxPoint) seg->GetSeg().B,
753  seg->GetWidth() + aInflateValue * 2, aError, aErrorLoc );
754 
755  return true;
756 }
757 
758 
760  PCB_LAYER_ID aLayer, int aClearance, int aError,
761  ERROR_LOC aErrorLoc, bool aIgnoreLineWidth ) const
762 {
763  wxASSERT_MSG( !aIgnoreLineWidth, "IgnoreLineWidth has no meaning for zones." );
764 
765  if( !m_FilledPolysList.count( aLayer ) )
766  return;
767 
768  aCornerBuffer = m_FilledPolysList.at( aLayer );
769 
770  int numSegs = GetArcToSegmentCount( aClearance, aError, 360.0 );
771  aCornerBuffer.Inflate( aClearance, numSegs );
773 }
774 
775 
777  PCB_LAYER_ID aLayer, int aClearance,
778  int aError, ERROR_LOC aErrorLoc,
779  bool aIgnoreLineWidth ) const
780 {
781  wxASSERT_MSG( !aIgnoreLineWidth, "IgnoreLineWidth has no meaning for dimensions." );
782 
783  for( const std::shared_ptr<SHAPE>& shape : m_shapes )
784  {
785  const SHAPE_CIRCLE* circle = dynamic_cast<const SHAPE_CIRCLE*>( shape.get() );
786  const SHAPE_SEGMENT* seg = dynamic_cast<const SHAPE_SEGMENT*>( shape.get() );
787 
788  if( circle )
789  {
790  TransformCircleToPolygon( aCornerBuffer, (wxPoint) circle->GetCenter(),
791  circle->GetRadius() + m_lineThickness / 2 + aClearance,
792  aError, aErrorLoc );
793  }
794  else if( seg )
795  {
796  TransformOvalToPolygon( aCornerBuffer, (wxPoint) seg->GetSeg().A,
797  (wxPoint) seg->GetSeg().B, m_lineThickness + 2 * aClearance,
798  aError, aErrorLoc );
799  }
800  else
801  {
802  wxFAIL_MSG( "DIMENSION::TransformShapeWithClearanceToPolygon unexpected shape type." );
803  }
804  }
805 }
806 
bool TransformHoleWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, int aError, ERROR_LOC aErrorLoc) const
Build the corner list of the polygonal drill shape in the board coordinate system.
virtual double GetDrawRotation() const override
Definition: fp_text.cpp:236
wxPoint GetArcEnd() const
Definition: pcb_shape.cpp:374
bool IsPolyShapeValid() const
Definition: pcb_shape.cpp:1215
bool IsBold() const
Definition: eda_text.h:190
bool IsFilled() const
Definition: pcb_shape.h:96
void TransformTextShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc) const
Convert the text to a polygonSet describing the actual character strokes (one per segment).
wxPoint m_end
Definition: pcb_shape.h:49
wxPoint m_Start
Line start point.
Definition: track.h:256
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:206
bool IsMirrored() const
Definition: eda_text.h:196
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
ZONES & Zones()
Definition: board.h:311
int GetRadius() const
Definition: shape_circle.h:107
void ConvertBrdLayerToPolygonalContours(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aOutlines) const
Build a set of polygons which are the outlines of copper items (pads, tracks, vias,...
static void addTextSegmToPoly(int x0, int y0, int xf, int yf, void *aData)
wxSize m_deltaSize
Definition: pad.h:740
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
void TransformTextShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc) const
Function TransformTextShapeWithClearanceToPolygon Convert the text to a polygonSet describing the act...
const wxPoint & GetStart() const
Definition: track.h:116
void GetPoly(std::vector< wxPoint > &aOutput, int aMinSegLen=0)
Convert a Bezier curve to a polygon.
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
Definition: pcb_shape.h:201
int color
Definition: DXF_plotter.cpp:60
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth=false) const override
Convert the item shape to a closed polygon.
std::vector< wxPoint > GetRectCorners() const
Definition: pcb_shape.cpp:971
EDA_RECT GetTextBox(int aLine=-1, bool aInvertY=false) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition: eda_text.cpp:223
double GetOrientation() const
Definition: footprint.h:186
static void isPlated(LIBEVAL::CONTEXT *aCtx, void *self)
double GetTextAngle() const
Definition: eda_text.h:181
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aError, ERROR_LOC aErrorLoc)
convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corner...
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Return a SHAPE object representing the pad's hole.
Definition: pad.cpp:285
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
wxPoint m_pos
Definition: pad.h:681
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
const VECTOR2I GetCenter() const
Definition: shape_circle.h:112
Definition: color4d.h:44
void TransformBoundingBoxWithClearanceToPolygon(SHAPE_POLY_SET *aCornerBuffer, int aClearanceValue) const
Convert the text bounding box to a rectangular polygon depending on the text orientation,...
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
void Inflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Perform outline inflation/deflation.
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth) const override
Convert the item shape to a closed polygon.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
TRACKS m_tracks
Definition: board.h:203
const SEG & GetSeg() const
int GetEffectiveTextPenWidth(int aDefaultWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultWidth.
Definition: eda_text.cpp:157
int m_Width
Thickness of track, or via diameter.
Definition: track.h:255
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
int GetBottom() const
Definition: eda_rect.h:119
wxPoint GetArcStart() const
Definition: pcb_shape.h:179
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:462
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Function TransformShapeWithClearanceToPolygon Convert the track shape to a closed polygon Used in fil...
polygon (not yet used for tracks, but could be in microwave apps)
bool IsItalic() const
Definition: eda_text.h:187
FP_TEXT & Reference()
Definition: footprint.h:463
void TransformOvalToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc)
convert a oblong shape to a polygon, using multiple segments It is similar to TransformRoundedEndsSeg...
#define DEFAULT_TEXT_WIDTH
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:53
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth) const override
Convert the item shape to a closed polygon.
const std::vector< wxPoint > BuildPolyPointsList() const
Build and return the list of corners in a std::vector<wxPoint> It must be used only to convert the SH...
Definition: pcb_shape.cpp:1198
const wxSize & GetDrillSize() const
Definition: pad.h:242
wxPoint ShapePos() const
Definition: pad.cpp:656
like PAD_PTH, but not plated
PCB_LAYER_ID
A quick note on layer IDs:
const wxPoint & GetMid() const
Definition: track.h:292
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:205
int GetMinThickness() const
Definition: zone.h:241
#define NULL
void Move(const VECTOR2I &aVector) override
Represent a set of closed polygons.
const wxPoint GetOrigin() const
Definition: eda_rect.h:106
TSEGM_2_POLY_PRMS prms
const wxSize & GetTextSize() const
Definition: eda_text.h:245
segment with non rounded ends
wxPoint m_End
Line end point.
Definition: track.h:257
wxPoint GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: pcb_shape.cpp:342
virtual BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:46
int GetRight() const
Definition: eda_rect.h:116
double m_orient
Definition: pad.h:751
PAD_SHAPE GetShape() const
Definition: pad.h:169
DRAWINGS & GraphicalItems()
Definition: footprint.h:167
a few functions useful in geometry calculations.
void Simplify(POLYGON_MODE aFastMode)
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
int GetCircleToPolyCorrection(int aMaxError)
void TransformSolidAreasShapesToPolygon(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer, int aError=ARC_HIGH_DEF) const
Convert solid areas full shapes to polygon set (the full shape is the polygon area with a thick outli...
DRAWINGS m_drawings
Definition: board.h:201
void MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon, PCB_LAYER_ID aLayer, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Merge all basic shapes to a SHAPE_POLY_SET.
int NewOutline()
Creates a new hole in a given outline.
void TransformPadsWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc, bool aSkipNPTHPadsWihNoCopper=false, bool aSkipPlatedPads=false, bool aSkipNonPlatedPads=false) const
Generate pads shapes on layer aLayer as polygons and adds these polygons to aCornerBuffer.
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
void GRText(wxDC *aDC, const wxPoint &aPos, COLOR4D aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, void(*aCallback)(int x0, int y0, int xf, int yf, void *aData), void *aCallbackData, PLOTTER *aPlotter)
Function GRText Draw a graphic text (like footprint texts)
Definition: gr_text.cpp:131
int GetRoundRectCornerRadius() const
Definition: pad.cpp:236
wxSize m_size
Definition: pad.h:715
wxPoint m_start
Definition: pcb_shape.h:48
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aMaxError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
static wxString PCB_SHAPE_TYPE_T_asString(PCB_SHAPE_TYPE a)
Definition: board_item.h:59
Bezier curves to polygon converter.
Definition: bezier_curves.h:36
double GetChamferRectRatio() const
Definition: pad.h:532
int m_width
Definition: pcb_shape.h:46
FOOTPRINT * GetParentFootprint() const
Function GetParentFootprint returns a pointer to the parent footprint, or NULL if PCB_SHAPE does not ...
Definition: pcb_shape.cpp:479
Definition: track.h:262
void TransformFPShapesWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool aIncludeText=true, bool aIncludeShapes=true) const
Generate shapes of graphic items (outlines) on layer aLayer as polygons and adds these polygons to aC...
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
std::vector< std::shared_ptr< SHAPE > > m_shapes
Definition: dimension.h:302
VECTOR2I A
Definition: seg.h:49
Handle the component boundary box.
Definition: eda_rect.h:42
double DECIDEG2RAD(double deg)
Definition: trigo.h:235
usual segment : line with rounded ends
static std::string PAD_SHAPE_T_asString(PAD_SHAPE a)
Definition: pad_shapes.h:47
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aCornerBuffer, wxPoint aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc)
Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines.
void InflateWithLinkedHoles(int aFactor, int aCircleSegmentsCount, POLYGON_MODE aFastMode)
Perform outline inflation/deflation, using round corners.
wxPoint GetPosition() const override
Definition: footprint.h:182
const wxPoint & GetEnd() const
Definition: track.h:113
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
int GetChamferPositions() const
Definition: pad.h:542
const wxPoint & GetTextPos() const
Definition: eda_text.h:254
wxPoint m_bezierC1
Definition: pcb_shape.h:54
FOOTPRINTS m_footprints
Definition: board.h:202
int m_lineThickness
Thickness used for all graphics in the dimension.
Definition: dimension.h:289
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
wxPoint GetArcMid() const
Definition: pcb_shape.cpp:392
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the zone shape to a closed polygon Used in filling zones calculations Circles and arcs are ap...
Definition: pad.h:60
Arcs (with rounded ends)
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Function TransformShapeWithClearanceToPolygon Convert the draw segment to a closed polygon Used in fi...
virtual wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: fp_text.cpp:398
wxPoint m_bezierC2
Definition: pcb_shape.h:55
int GetWidth() const
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
PCB_SHAPE_TYPE m_shape
Definition: pcb_shape.h:52
static constexpr int Millimeter2iu(double mm)
std::map< PCB_LAYER_ID, SHAPE_POLY_SET > m_FilledPolysList
Definition: zone.h:914
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
PADS m_pads
Definition: footprint.h:683
void TransformArcToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aMid, wxPoint aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc)
Function TransformArcToPolygon Creates a polygon from an Arc Convert arcs to multiple straight segmen...
Definition: track.h:83
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:363
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163
void TransformRingToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCentre, int aRadius, int aWidth, int aError, ERROR_LOC aErrorLoc)
Function TransformRingToPolygon Creates a polygon from a ring Convert arcs to multiple straight segme...
bool GetFilledPolysUseThickness() const
Definition: zone.h:686
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:98
VECTOR2I B
Definition: seg.h:50