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 <macros.h>
27 #include <bezier_curves.h>
28 #include <board_design_settings.h>
29 #include <trigo.h>
30 #include <board.h>
31 #include <pad.h>
32 #include <pcb_dimension.h>
33 #include <pcb_track.h>
34 #include <pcb_shape.h>
35 #include <pcb_text.h>
36 #include <zone.h>
37 #include <footprint.h>
38 #include <fp_shape.h>
41 #include <geometry/shape_segment.h>
42 #include <geometry/shape_circle.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 
57 
59 
60 
61 // This is a call back function, used by GRText to draw the 3D text shape:
62 static void addTextSegmToPoly( int x0, int y0, int xf, int yf, void* aData )
63 {
64  TSEGM_2_POLY_PRMS* prm = static_cast<TSEGM_2_POLY_PRMS*>( aData );
65  TransformOvalToPolygon( *prm->m_cornerBuffer, wxPoint( x0, y0 ), wxPoint( xf, yf ),
66  prm->m_textWidth, prm->m_error, ERROR_INSIDE );
67 }
68 
69 
71  SHAPE_POLY_SET& aOutlines ) const
72 {
73  int maxError = GetDesignSettings().m_MaxError;
74 
75  // convert tracks and vias:
76  for( const PCB_TRACK* track : m_tracks )
77  {
78  if( !track->IsOnLayer( aLayer ) )
79  continue;
80 
81  track->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
82  ERROR_INSIDE );
83  }
84 
85  // convert pads and other copper items in footprints
86  for( const FOOTPRINT* footprint : m_footprints )
87  {
88  footprint->TransformPadsWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
89  ERROR_INSIDE );
90 
91  // Micro-wave footprints may have items on copper layers
92  footprint->TransformFPShapesWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
94  true, /* include text */
95  true /* include shapes */ );
96 
97  for( const ZONE* zone : footprint->Zones() )
98  {
99  if( zone->GetLayerSet().test( aLayer ) )
100  zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
101  }
102  }
103 
104  // convert copper zones
105  for( const ZONE* zone : Zones() )
106  {
107  if( zone->GetLayerSet().test( aLayer ) )
108  zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines );
109  }
110 
111  // convert graphic items on copper layers (texts)
112  for( const BOARD_ITEM* item : m_drawings )
113  {
114  if( !item->IsOnLayer( aLayer ) )
115  continue;
116 
117  switch( item->Type() )
118  {
119  case PCB_SHAPE_T:
120  {
121  const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( item );
122  shape->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
123  ERROR_INSIDE );
124  break;
125  }
126 
127  case PCB_TEXT_T:
128  {
129  const PCB_TEXT* text = static_cast<const PCB_TEXT*>( item );
130  text->TransformTextShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError,
131  ERROR_INSIDE );
132  break;
133  }
134 
135  default:
136  break;
137  }
138  }
139 }
140 
141 
143  PCB_LAYER_ID aLayer, int aClearance,
144  int aMaxError, ERROR_LOC aErrorLoc,
145  bool aSkipNPTHPadsWihNoCopper,
146  bool aSkipPlatedPads,
147  bool aSkipNonPlatedPads ) const
148 {
149  for( const PAD* pad : m_pads )
150  {
151  if( aLayer != UNDEFINED_LAYER && !pad->IsOnLayer(aLayer) )
152  continue;
153 
154  if( !pad->FlashLayer( aLayer ) && IsCopperLayer( aLayer ) )
155  continue;
156 
157  // NPTH pads are not drawn on layers if the shape size and pos is the same
158  // as their hole:
159  if( aSkipNPTHPadsWihNoCopper && pad->GetAttribute() == PAD_ATTRIB::NPTH )
160  {
161  if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
162  {
163  switch( pad->GetShape() )
164  {
165  case PAD_SHAPE::CIRCLE:
166  if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
167  continue;
168 
169  break;
170 
171  case PAD_SHAPE::OVAL:
172  if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
173  continue;
174 
175  break;
176 
177  default:
178  break;
179  }
180  }
181  }
182 
183  const bool isPlated = ( ( aLayer == F_Cu ) && pad->FlashLayer( F_Mask ) ) ||
184  ( ( aLayer == B_Cu ) && pad->FlashLayer( B_Mask ) );
185 
186  if( aSkipPlatedPads && isPlated )
187  continue;
188 
189  if( aSkipNonPlatedPads && !isPlated )
190  continue;
191 
192  wxSize clearance( aClearance, aClearance );
193 
194  switch( aLayer )
195  {
196  case F_Mask:
197  case B_Mask:
198  clearance.x += pad->GetSolderMaskMargin();
199  clearance.y += pad->GetSolderMaskMargin();
200  break;
201 
202  case F_Paste:
203  case B_Paste:
204  clearance += pad->GetSolderPasteMargin();
205  break;
206 
207  default:
208  break;
209  }
210 
211  // Our standard TransformShapeWithClearanceToPolygon() routines can't handle differing
212  // x:y clearance values (which get generated when a relative paste margin is used with
213  // an oblong pad). So we apply this huge hack and fake a larger pad to run the transform
214  // on.
215  // Of course being a hack it falls down when dealing with custom shape pads (where the
216  // size is only the size of the anchor), so for those we punt and just use clearance.x.
217 
218  if( ( clearance.x < 0 || clearance.x != clearance.y )
219  && pad->GetShape() != PAD_SHAPE::CUSTOM )
220  {
221  PAD dummy( *pad );
222  dummy.SetSize( pad->GetSize() + clearance + clearance );
223  dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0,
224  aMaxError, aErrorLoc );
225  }
226  else
227  {
228  pad->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, clearance.x,
229  aMaxError, aErrorLoc );
230  }
231  }
232 }
233 
243  PCB_LAYER_ID aLayer, int aClearance,
244  int aError, ERROR_LOC aErrorLoc,
245  bool aIncludeText,
246  bool aIncludeShapes ) const
247 {
248  std::vector<FP_TEXT*> texts; // List of FP_TEXT to convert
249 
250  for( BOARD_ITEM* item : GraphicalItems() )
251  {
252  if( item->Type() == PCB_FP_TEXT_T && aIncludeText )
253  {
254  FP_TEXT* text = static_cast<FP_TEXT*>( item );
255 
256  if( aLayer != UNDEFINED_LAYER && text->GetLayer() == aLayer && text->IsVisible() )
257  texts.push_back( text );
258  }
259 
260  if( item->Type() == PCB_FP_SHAPE_T && aIncludeShapes )
261  {
262  const FP_SHAPE* outline = static_cast<FP_SHAPE*>( item );
263 
264  if( aLayer != UNDEFINED_LAYER && outline->GetLayer() == aLayer )
265  {
266  outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, aLayer, 0,
267  aError, aErrorLoc );
268  }
269  }
270  }
271 
272  if( aIncludeText )
273  {
274  if( Reference().GetLayer() == aLayer && Reference().IsVisible() )
275  texts.push_back( &Reference() );
276 
277  if( Value().GetLayer() == aLayer && Value().IsVisible() )
278  texts.push_back( &Value() );
279  }
280 
281  for( const FP_TEXT* text : texts )
282  {
283  text->TransformTextShapeWithClearanceToPolygon( aCornerBuffer, aLayer, aClearance,
284  aError, aErrorLoc );
285  }
286 }
287 
288 
290  PCB_LAYER_ID aLayer, int aClearance,
291  int aError, ERROR_LOC aErrorLoc ) const
292 {
293  prms.m_cornerBuffer = &aCornerBuffer;
294  prms.m_textWidth = GetEffectiveTextPenWidth() + ( 2 * aClearance );
295  prms.m_error = aError;
296  wxSize size = GetTextSize();
297  int penWidth = GetEffectiveTextPenWidth();
298 
299  if( IsMirrored() )
300  size.x = -size.x;
301 
302  GRText( nullptr, GetTextPos(), BLACK, GetShownText(), GetDrawRotation(), size,
303  GetHorizJustify(), GetVertJustify(), penWidth, IsItalic(), IsBold(),
305 }
306 
307 
309  PCB_LAYER_ID aLayer, int aClearance,
310  int aError, ERROR_LOC aErrorLoc,
311  bool aIgnoreLineWidth ) const
312 {
313  SHAPE_POLY_SET buffer;
315 
316  const FOOTPRINT* parentFootprint = static_cast<const FOOTPRINT*>( m_parent );
317 
318  if( parentFootprint )
319  buffer.Rotate( DECIDEG2RAD( GetDrawRotation() ), GetTextPos() );
320 
321  aCornerBuffer.Append( buffer );
322 }
323 
324 
326  int aError ) const
327 {
328  if( !m_FilledPolysList.count( aLayer ) || m_FilledPolysList.at( aLayer ).IsEmpty() )
329  return;
330 
331  // Just add filled areas if filled polygons outlines have no thickness
333  {
334  const SHAPE_POLY_SET& polys = m_FilledPolysList.at( aLayer );
335  aCornerBuffer.Append( polys );
336  return;
337  }
338 
339  // Filled areas have polygons with outline thickness.
340  // we must create the polygons and add inflated polys
341  SHAPE_POLY_SET polys = m_FilledPolysList.at( aLayer );
342 
343  auto board = GetBoard();
344  int maxError = ARC_HIGH_DEF;
345 
346  if( board )
347  maxError = board->GetDesignSettings().m_MaxError;
348 
349  int numSegs = GetArcToSegmentCount( GetMinThickness(), maxError, 360.0 );
350 
352 
353  aCornerBuffer.Append( polys );
354 }
355 
356 
358  int aClearanceValue ) const
359 {
360  if( GetText().Length() == 0 )
361  return;
362 
363  wxPoint corners[4]; // Buffer of polygon corners
364 
365  EDA_RECT rect = GetTextBox();
366  rect.Inflate( aClearanceValue + Millimeter2iu( DEFAULT_TEXT_WIDTH ) );
367  corners[0].x = rect.GetOrigin().x;
368  corners[0].y = rect.GetOrigin().y;
369  corners[1].y = corners[0].y;
370  corners[1].x = rect.GetRight();
371  corners[2].x = corners[1].x;
372  corners[2].y = rect.GetBottom();
373  corners[3].y = corners[2].y;
374  corners[3].x = corners[0].x;
375 
376  aCornerBuffer->NewOutline();
377 
378  for( wxPoint& corner : corners )
379  {
380  // Rotate polygon
381  RotatePoint( &corner.x, &corner.y, GetTextPos().x, GetTextPos().y, GetTextAngle() );
382  aCornerBuffer->Append( corner.x, corner.y );
383  }
384 }
385 
386 
388  PCB_LAYER_ID aLayer, int aClearanceValue,
389  int aError, ERROR_LOC aErrorLoc ) const
390 {
391  wxSize size = GetTextSize();
392 
393  if( IsMirrored() )
394  size.x = -size.x;
395 
396  int penWidth = GetEffectiveTextPenWidth();
397 
398  prms.m_cornerBuffer = &aCornerBuffer;
399  prms.m_textWidth = GetEffectiveTextPenWidth() + ( 2 * aClearanceValue );
400  prms.m_error = aError;
401  COLOR4D color; // not actually used, but needed by GRText
402 
403  GRText( nullptr, GetTextPos(), color, GetShownText(), GetTextAngle(), size, GetHorizJustify(),
404  GetVertJustify(), penWidth, IsItalic(), IsBold(), addTextSegmToPoly, &prms );
405 }
406 
407 
409  PCB_LAYER_ID aLayer, int aClearance,
410  int aError, ERROR_LOC aErrorLoc,
411  bool aIgnoreLineWidth ) const
412 {
413  EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( &aCornerBuffer, aClearance );
414 }
415 
416 
418  int aClearanceValue,
419  int aError, ERROR_LOC aErrorLoc,
420  bool ignoreLineWidth ) const
421 {
422  int width = ignoreLineWidth ? 0 : m_width;
423 
424  width += 2 * aClearanceValue;
425 
426  switch( m_shape )
427  {
428  case SHAPE_T::CIRCLE:
429  if( IsFilled() )
430  {
431  TransformCircleToPolygon( aCornerBuffer, getCenter(), GetRadius() + width / 2, aError,
432  aErrorLoc );
433  }
434  else
435  {
436  TransformRingToPolygon( aCornerBuffer, getCenter(), GetRadius(), width, aError,
437  aErrorLoc );
438  }
439 
440  break;
441 
442  case SHAPE_T::RECT:
443  {
444  std::vector<wxPoint> pts = GetRectCorners();
445 
446  if( IsFilled() )
447  {
448  aCornerBuffer.NewOutline();
449 
450  for( const wxPoint& pt : pts )
451  aCornerBuffer.Append( pt );
452  }
453 
454  if( width > 0 || !IsFilled() )
455  {
456  // Add in segments
457  TransformOvalToPolygon( aCornerBuffer, pts[0], pts[1], width, aError, aErrorLoc );
458  TransformOvalToPolygon( aCornerBuffer, pts[1], pts[2], width, aError, aErrorLoc );
459  TransformOvalToPolygon( aCornerBuffer, pts[2], pts[3], width, aError, aErrorLoc );
460  TransformOvalToPolygon( aCornerBuffer, pts[3], pts[0], width, aError, aErrorLoc );
461  }
462 
463  break;
464  }
465 
466  case SHAPE_T::ARC:
467  TransformArcToPolygon( aCornerBuffer, GetStart(), GetArcMid(), GetEnd(), width, aError,
468  aErrorLoc );
469  break;
470 
471  case SHAPE_T::SEGMENT:
472  TransformOvalToPolygon( aCornerBuffer, GetStart(), GetEnd(), width, aError, aErrorLoc );
473  break;
474 
475  case SHAPE_T::POLY:
476  {
477  if( !IsPolyShapeValid() )
478  break;
479 
480  // The polygon is expected to be a simple polygon; not self intersecting, no hole.
481  double orientation = getParentOrientation();
482  wxPoint offset = getParentPosition();
483 
484  // Build the polygon with the actual position and orientation:
485  std::vector<wxPoint> poly;
486  DupPolyPointsList( poly );
487 
488  for( wxPoint& point : poly )
489  {
490  RotatePoint( &point, orientation );
491  point += offset;
492  }
493 
494  if( IsFilled() )
495  {
496  aCornerBuffer.NewOutline();
497 
498  for( const wxPoint& point : poly )
499  aCornerBuffer.Append( point.x, point.y );
500  }
501 
502  if( width > 0 || !IsFilled() )
503  {
504  wxPoint pt1( poly[ poly.size() - 1] );
505 
506  for( const wxPoint& pt2 : poly )
507  {
508  if( pt2 != pt1 )
509  TransformOvalToPolygon( aCornerBuffer, pt1, pt2, width, aError, aErrorLoc );
510 
511  pt1 = pt2;
512  }
513  }
514 
515  break;
516  }
517 
518  case SHAPE_T::BEZIER:
519  {
520  std::vector<wxPoint> ctrlPts = { GetStart(), GetBezierC1(), GetBezierC2(), GetEnd() };
521  BEZIER_POLY converter( ctrlPts );
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,
528  aErrorLoc );
529  }
530 
531  break;
532  }
533 
534  default:
536  break;
537  }
538 }
539 
540 
542  PCB_LAYER_ID aLayer, int aClearanceValue,
543  int aError, ERROR_LOC aErrorLoc,
544  bool ignoreLineWidth ) const
545 {
546  EDA_SHAPE::TransformShapeWithClearanceToPolygon( aCornerBuffer, aClearanceValue, aError,
547  aErrorLoc, ignoreLineWidth );
548 }
549 
550 
552  PCB_LAYER_ID aLayer, int aClearanceValue,
553  int aError, ERROR_LOC aErrorLoc,
554  bool ignoreLineWidth ) const
555 {
556  wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for tracks." );
557 
558 
559  switch( Type() )
560  {
561  case PCB_VIA_T:
562  {
563  int radius = ( m_Width / 2 ) + aClearanceValue;
564  TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aError, aErrorLoc );
565  break;
566  }
567 
568  case PCB_ARC_T:
569  {
570  const PCB_ARC* arc = static_cast<const PCB_ARC*>( this );
571  int width = m_Width + ( 2 * aClearanceValue );
572 
573  TransformArcToPolygon( aCornerBuffer, arc->GetStart(), arc->GetMid(),
574  arc->GetEnd(), width, aError, aErrorLoc );
575  break;
576  }
577 
578  default:
579  {
580  int width = m_Width + ( 2 * aClearanceValue );
581 
582  TransformOvalToPolygon( aCornerBuffer, m_Start, m_End, width, aError, aErrorLoc );
583  break;
584  }
585  }
586 }
587 
588 
590  PCB_LAYER_ID aLayer, int aClearanceValue,
591  int aError, ERROR_LOC aErrorLoc,
592  bool ignoreLineWidth ) const
593 {
594  wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for pads." );
595 
596  // minimal segment count to approximate a circle to create the polygonal pad shape
597  // This minimal value is mainly for very small pads, like SM0402.
598  // Most of time pads are using the segment count given by aError value.
599  const int pad_min_seg_per_circle_count = 16;
600  double angle = m_orient;
601  int dx = m_size.x / 2;
602  int dy = m_size.y / 2;
603 
604  wxPoint padShapePos = ShapePos(); // Note: for pad having a shape offset,
605  // the pad position is NOT the shape position
606 
607  switch( GetShape() )
608  {
609  case PAD_SHAPE::CIRCLE:
610  case PAD_SHAPE::OVAL:
611  // Note: dx == dy is not guaranteed for circle pads in legacy boards
612  if( dx == dy || ( GetShape() == PAD_SHAPE::CIRCLE ) )
613  {
614  TransformCircleToPolygon( aCornerBuffer, padShapePos, dx + aClearanceValue, aError,
615  aErrorLoc, pad_min_seg_per_circle_count );
616  }
617  else
618  {
619  int half_width = std::min( dx, dy );
620  wxPoint delta( dx - half_width, dy - half_width );
621 
622  RotatePoint( &delta, angle );
623 
624  TransformOvalToPolygon( aCornerBuffer, padShapePos - delta, padShapePos + delta,
625  ( half_width + aClearanceValue ) * 2, aError, aErrorLoc,
626  pad_min_seg_per_circle_count );
627  }
628 
629  break;
630 
632  case PAD_SHAPE::RECT:
633  {
634  int ddx = GetShape() == PAD_SHAPE::TRAPEZOID ? m_deltaSize.x / 2 : 0;
635  int ddy = GetShape() == PAD_SHAPE::TRAPEZOID ? m_deltaSize.y / 2 : 0;
636 
637  SHAPE_POLY_SET outline;
638  TransformTrapezoidToPolygon( outline, padShapePos, m_size, angle, ddx, ddy,
639  aClearanceValue, aError, aErrorLoc );
640  aCornerBuffer.Append( outline );
641  break;
642  }
643 
646  {
647  bool doChamfer = GetShape() == PAD_SHAPE::CHAMFERED_RECT;
648 
649  SHAPE_POLY_SET outline;
650  TransformRoundChamferedRectToPolygon( outline, padShapePos, m_size, angle,
652  doChamfer ? GetChamferRectRatio() : 0,
653  doChamfer ? GetChamferPositions() : 0,
654  aClearanceValue, aError, aErrorLoc );
655  aCornerBuffer.Append( outline );
656  break;
657  }
658 
659  case PAD_SHAPE::CUSTOM:
660  {
661  SHAPE_POLY_SET outline;
662  MergePrimitivesAsPolygon( &outline, aErrorLoc );
663  outline.Rotate( -DECIDEG2RAD( m_orient ) );
664  outline.Move( VECTOR2I( m_pos ) );
665 
666  if( aClearanceValue )
667  {
668  int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ),
669  pad_min_seg_per_circle_count );
670  int clearance = aClearanceValue;
671 
672  if( aErrorLoc == ERROR_OUTSIDE )
673  {
674  int actual_error = CircleToEndSegmentDeltaRadius( clearance, numSegs );
675  clearance += GetCircleToPolyCorrection( actual_error );
676  }
677 
678  outline.Inflate( clearance, numSegs );
681  }
682 
683  aCornerBuffer.Append( outline );
684  break;
685  }
686 
687  default:
688  wxFAIL_MSG( "PAD::TransformShapeWithClearanceToPolygon no implementation for "
690  break;
691  }
692 }
693 
694 
695 
696 bool PAD::TransformHoleWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aInflateValue,
697  int aError, ERROR_LOC aErrorLoc ) const
698 {
699  wxSize drillsize = GetDrillSize();
700 
701  if( !drillsize.x || !drillsize.y )
702  return false;
703 
704  const SHAPE_SEGMENT* seg = GetEffectiveHoleShape();
705 
706  TransformOvalToPolygon( aCornerBuffer, (wxPoint) seg->GetSeg().A, (wxPoint) seg->GetSeg().B,
707  seg->GetWidth() + aInflateValue * 2, aError, aErrorLoc );
708 
709  return true;
710 }
711 
712 
714  PCB_LAYER_ID aLayer, int aClearance, int aError,
715  ERROR_LOC aErrorLoc, bool aIgnoreLineWidth ) const
716 {
717  wxASSERT_MSG( !aIgnoreLineWidth, "IgnoreLineWidth has no meaning for zones." );
718 
719  if( !m_FilledPolysList.count( aLayer ) )
720  return;
721 
722  aCornerBuffer = m_FilledPolysList.at( aLayer );
723 
724  int numSegs = GetArcToSegmentCount( aClearance, aError, 360.0 );
725  aCornerBuffer.Inflate( aClearance, numSegs );
727 }
728 
729 
731  PCB_LAYER_ID aLayer, int aClearance,
732  int aError, ERROR_LOC aErrorLoc,
733  bool aIgnoreLineWidth ) const
734 {
735  wxASSERT_MSG( !aIgnoreLineWidth, "IgnoreLineWidth has no meaning for dimensions." );
736 
737  for( const std::shared_ptr<SHAPE>& shape : m_shapes )
738  {
739  const SHAPE_CIRCLE* circle = dynamic_cast<const SHAPE_CIRCLE*>( shape.get() );
740  const SHAPE_SEGMENT* seg = dynamic_cast<const SHAPE_SEGMENT*>( shape.get() );
741 
742  if( circle )
743  {
744  TransformCircleToPolygon( aCornerBuffer, (wxPoint) circle->GetCenter(),
745  circle->GetRadius() + m_lineThickness / 2 + aClearance,
746  aError, aErrorLoc );
747  }
748  else if( seg )
749  {
750  TransformOvalToPolygon( aCornerBuffer, (wxPoint) seg->GetSeg().A,
751  (wxPoint) seg->GetSeg().B, m_lineThickness + 2 * aClearance,
752  aError, aErrorLoc );
753  }
754  else
755  {
756  wxFAIL_MSG( "PCB_DIMENSION_BASE::TransformShapeWithClearanceToPolygon unexpected "
757  "shape type." );
758  }
759  }
760 }
761 
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:239
bool IsBold() const
Definition: eda_text.h:183
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:479
SHAPE_T m_shape
Definition: eda_shape.h:296
wxPoint m_Start
Line start point.
Definition: pcb_track.h:240
void TransformTextShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc) const
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:199
bool IsMirrored() const
Definition: eda_text.h:189
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
ZONES & Zones()
Definition: board.h:239
int CircleToEndSegmentDeltaRadius(int aInnerCircleRadius, int aSegCount)
int GetRadius() const
Definition: shape_circle.h:107
const wxPoint & GetEnd() const
Definition: pcb_track.h:105
wxPoint getCenter() const
Definition: eda_shape.cpp:390
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
std::vector< std::shared_ptr< SHAPE > > m_shapes
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
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
Return the starting point of the graphic.
Definition: eda_shape.h:97
void GetPoly(std::vector< wxPoint > &aOutput, int aMinSegLen=0)
Convert a Bezier curve to a polygon.
int color
Definition: DXF_plotter.cpp:57
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.
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth) const
Convert the shape to a closed polygon.
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:229
static void isPlated(LIBEVAL::CONTEXT *aCtx, void *self)
void DupPolyPointsList(std::vector< wxPoint > &aBuffer) const
Duplicate the list of corners in a std::vector<wxPoint>
Definition: eda_shape.cpp:1126
double GetTextAngle() const
Definition: eda_text.h:174
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
virtual wxPoint getParentPosition() const =0
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Return a SHAPE object representing the pad's hole.
Definition: pad.cpp:304
void GRText(wxDC *aDC, const wxPoint &aPos, const 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)
Draw a graphic text (like footprint texts).
Definition: gr_text.cpp:129
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.
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...
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:229
bool IsPolyShapeValid() const
Definition: eda_shape.cpp:1143
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:1122
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:590
const SEG & GetSeg() const
int GetEffectiveTextPenWidth(int aDefaultWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultWidth.
Definition: eda_text.cpp:149
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
This file contains miscellaneous commonly used macros and functions.
int GetBottom() const
Definition: eda_rect.h:114
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:499
wxPoint m_End
Line end point.
Definition: pcb_track.h:241
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
bool IsFilled() const
Definition: eda_shape.h:81
bool IsItalic() const
Definition: eda_text.h:180
FP_TEXT & Reference()
Definition: footprint.h:500
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:72
const wxPoint & GetBezierC1() const
Definition: eda_shape.h:145
#define DEFAULT_TEXT_WIDTH
std::vector< wxPoint > GetRectCorners() const
Definition: eda_shape.cpp:929
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:56
const wxSize & GetDrillSize() const
Definition: pad.h:243
wxPoint ShapePos() const
Definition: pad.cpp:671
like PAD_PTH, but not plated
const wxPoint & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:122
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:198
int GetMinThickness() const
Definition: zone.h:244
void Move(const VECTOR2I &aVector) override
Represent a set of closed polygons.
const wxPoint GetOrigin() const
Definition: eda_rect.h:101
TSEGM_2_POLY_PRMS prms
const wxSize & GetTextSize() const
Definition: eda_text.h:238
int GetRight() const
Definition: eda_rect.h:111
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aCornerBuffer, const wxPoint &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
const wxPoint & GetBezierC2() const
Definition: eda_shape.h:148
void TransformTrapezoidToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aDeltaX, int aDeltaY, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle or trapezoid to a polygon.
double m_orient
Definition: pad.h:751
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:120
PAD_SHAPE GetShape() const
Definition: pad.h:170
DRAWINGS & GraphicalItems()
Definition: footprint.h:171
a few functions useful in geometry calculations.
void Simplify(POLYGON_MODE aFastMode)
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
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...
wxString SHAPE_T_asString() const
Definition: eda_shape.cpp:68
DRAWINGS m_drawings
Definition: board.h:1120
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.
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:796
void Inflate(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Perform outline inflation/deflation.
int GetRoundRectCornerRadius() const
Definition: pad.cpp:255
wxSize m_size
Definition: pad.h:715
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.
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.
int m_Width
Thickness of track, or via diameter.
Definition: pcb_track.h:239
Bezier curves to polygon converter.
Definition: bezier_curves.h:36
double GetChamferRectRatio() const
Definition: pad.h:532
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...
virtual double getParentOrientation() const =0
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:65
Definition: layer_ids.h:71
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
wxPoint GetArcMid() const
Definition: eda_shape.cpp:434
VECTOR2I A
Definition: seg.h:48
Handle the component boundary box.
Definition: eda_rect.h:42
double DECIDEG2RAD(double deg)
Definition: trigo.h:233
void TransformOvalToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aStart, const wxPoint &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
static std::string PAD_SHAPE_T_asString(PAD_SHAPE a)
Definition: pad_shapes.h:47
void InflateWithLinkedHoles(int aFactor, int aCircleSegmentsCount, POLYGON_MODE aFastMode)
Perform outline inflation/deflation, using round corners.
int m_lineThickness
Thickness used for all graphics in the dimension.
void MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Merge all basic shapes to a SHAPE_POLY_SET.
int GetChamferPositions() const
Definition: pad.h:542
const wxPoint & GetTextPos() const
Definition: eda_text.h:247
void TransformArcToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aStart, const wxPoint &aMid, const wxPoint &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arc to multiple straight segments.
FOOTPRINTS m_footprints
Definition: board.h:1121
constexpr int delta
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:36
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
int m_width
Definition: eda_shape.h:297
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...
int GetRadius() const
Definition: eda_shape.cpp:463
Definition: pad.h:57
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
virtual wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: fp_text.cpp:414
int GetWidth() const
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
static constexpr int Millimeter2iu(double mm)
std::map< PCB_LAYER_ID, SHAPE_POLY_SET > m_FilledPolysList
Definition: zone.h:917
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:140
const wxPoint & GetMid() const
Definition: pcb_track.h:273
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
void TransformRingToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aCentre, int aRadius, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arcs to multiple straight segments.
PADS m_pads
Definition: footprint.h:732
const wxPoint & GetStart() const
Definition: pcb_track.h:108
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
bool GetFilledPolysUseThickness() const
Definition: zone.h:689
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:103
VECTOR2I B
Definition: seg.h:49