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-2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2016 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 /***
26  * @file board_items_to_polygon_shape_transform.cpp
27  * @brief function to convert shapes of items ( pads, tracks... ) to polygons
28  */
29 
30 /* Function to convert pad and track shapes to polygons
31  * Used to fill zones areas and in 3D viewer
32  */
33 #include <vector>
34 
35 #include <fctsys.h>
36 #include <draw_graphic_text.h>
37 #include <pcbnew.h>
38 #include <pcb_edit_frame.h>
39 #include <trigo.h>
40 #include <class_board.h>
41 #include <class_pad.h>
42 #include <class_track.h>
43 #include <class_drawsegment.h>
44 #include <class_pcb_text.h>
45 #include <class_zone.h>
46 #include <class_module.h>
47 #include <class_edge_mod.h>
49 
50 // These variables are parameters used in addTextSegmToPoly.
51 // But addTextSegmToPoly is a call-back function,
52 // so we cannot send them as arguments.
53 static int s_textWidth;
56 
57 // This is a call back function, used by DrawGraphicText to draw the 3D text shape:
58 static void addTextSegmToPoly( int x0, int y0, int xf, int yf )
59 {
60  TransformRoundedEndsSegmentToPolygon( *s_cornerBuffer,
61  wxPoint( x0, y0), wxPoint( xf, yf ),
63 }
64 
65 
67 {
68  // Number of segments to convert a circle to a polygon
69  const int segcountforcircle = 18;
70  double correctionFactor = 1.0 / cos( M_PI / (segcountforcircle * 2) );
71 
72  // convert tracks and vias:
73  for( TRACK* track = m_Track; track != NULL; track = track->Next() )
74  {
75  if( !track->IsOnLayer( aLayer ) )
76  continue;
77 
78  track->TransformShapeWithClearanceToPolygon( aOutlines,
79  0, segcountforcircle, correctionFactor );
80  }
81 
82  // convert pads
83  for( MODULE* module = m_Modules; module != NULL; module = module->Next() )
84  {
85  module->TransformPadsShapesWithClearanceToPolygon( aLayer,
86  aOutlines, 0, segcountforcircle, correctionFactor );
87 
88  // Micro-wave modules may have items on copper layers
89  module->TransformGraphicShapesWithClearanceToPolygonSet( aLayer,
90  aOutlines, 0, segcountforcircle, correctionFactor );
91  }
92 
93  // convert copper zones
94  for( int ii = 0; ii < GetAreaCount(); ii++ )
95  {
96  ZONE_CONTAINER* zone = GetArea( ii );
97  PCB_LAYER_ID zonelayer = zone->GetLayer();
98 
99  if( zonelayer == aLayer )
101  aOutlines, segcountforcircle, correctionFactor );
102  }
103 
104  // convert graphic items on copper layers (texts)
105  for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
106  {
107  if( !item->IsOnLayer( aLayer ) )
108  continue;
109 
110  switch( item->Type() )
111  {
112  case PCB_LINE_T: // should not exist on copper layers
113  ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
114  aOutlines, 0, segcountforcircle, correctionFactor );
115  break;
116 
117  case PCB_TEXT_T:
118  ( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet(
119  aOutlines, 0, segcountforcircle, correctionFactor );
120  break;
121 
122  default:
123  break;
124  }
125  }
126 }
127 
128 
130  SHAPE_POLY_SET& aCornerBuffer,
131  int aInflateValue,
132  int aCircleToSegmentsCount,
133  double aCorrectionFactor,
134  bool aSkipNPTHPadsWihNoCopper ) const
135 {
136  D_PAD* pad = PadsList();
137 
138  wxSize margin;
139  for( ; pad != NULL; pad = pad->Next() )
140  {
141  if( aLayer != UNDEFINED_LAYER && !pad->IsOnLayer(aLayer) )
142  continue;
143 
144  // NPTH pads are not drawn on layers if the shape size and pos is the same
145  // as their hole:
146  if( aSkipNPTHPadsWihNoCopper && pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
147  {
148  if( pad->GetDrillSize() == pad->GetSize() && pad->GetOffset() == wxPoint( 0, 0 ) )
149  {
150  switch( pad->GetShape() )
151  {
152  case PAD_SHAPE_CIRCLE:
153  if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
154  continue;
155  break;
156 
157  case PAD_SHAPE_OVAL:
158  if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
159  continue;
160  break;
161 
162  default:
163  break;
164  }
165  }
166  }
167 
168  switch( aLayer )
169  {
170  case F_Mask:
171  case B_Mask:
172  margin.x = margin.y = pad->GetSolderMaskMargin() + aInflateValue;
173  break;
174 
175  case F_Paste:
176  case B_Paste:
177  margin = pad->GetSolderPasteMargin();
178  margin.x += aInflateValue;
179  margin.y += aInflateValue;
180  break;
181 
182  default:
183  margin.x = margin.y = aInflateValue;
184  break;
185  }
186 
187  pad->BuildPadShapePolygon( aCornerBuffer, margin,
188  aCircleToSegmentsCount, aCorrectionFactor );
189  }
190 }
191 
192 /* generate shapes of graphic items (outlines) on layer aLayer as polygons,
193  * and adds these polygons to aCornerBuffer
194  * aCornerBuffer = the buffer to store polygons
195  * aInflateValue = a value to inflate shapes
196  * aCircleToSegmentsCount = number of segments to approximate a circle
197  * aCorrectionFactor = the correction to apply to the circle radius
198  * to generate the polygon.
199  * if aCorrectionFactor = 1.0, the polygon is inside the circle
200  * the radius of circle approximated by segments is
201  * initial radius * aCorrectionFactor
202  */
204  PCB_LAYER_ID aLayer,
205  SHAPE_POLY_SET& aCornerBuffer,
206  int aInflateValue,
207  int aCircleToSegmentsCount,
208  double aCorrectionFactor,
209  int aCircleToSegmentsCountForTexts,
210  bool aIncludeText ) const
211 {
212  std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert
213  EDGE_MODULE* outline;
214 
215  for( EDA_ITEM* item = GraphicalItemsList(); item != NULL; item = item->Next() )
216  {
217  switch( item->Type() )
218  {
219  case PCB_MODULE_TEXT_T:
220  {
221  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
222 
223  if( ( aLayer != UNDEFINED_LAYER && text->GetLayer() == aLayer )
224  && text->IsVisible() )
225  texts.push_back( text );
226 
227  break;
228  }
229 
230  case PCB_MODULE_EDGE_T:
231  outline = (EDGE_MODULE*) item;
232 
233  if( aLayer != UNDEFINED_LAYER && outline->GetLayer() != aLayer )
234  break;
235 
236  outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, 0,
237  aCircleToSegmentsCount, aCorrectionFactor );
238  break;
239 
240  default:
241  break;
242  }
243  }
244 
245  if( !aIncludeText )
246  return;
247 
248  // Convert texts sur modules
249  if( Reference().GetLayer() == aLayer && Reference().IsVisible() )
250  texts.push_back( &Reference() );
251 
252  if( Value().GetLayer() == aLayer && Value().IsVisible() )
253  texts.push_back( &Value() );
254 
255  s_cornerBuffer = &aCornerBuffer;
256 
257  // To allow optimization of circles approximated by segments,
258  // aCircleToSegmentsCountForTexts, when not 0, is used.
259  // if 0 (default value) the aCircleToSegmentsCount is used
260  s_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
261  aCircleToSegmentsCountForTexts : aCircleToSegmentsCount;
262 
263  for( unsigned ii = 0; ii < texts.size(); ii++ )
264  {
265  TEXTE_MODULE *textmod = texts[ii];
266  s_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
267  wxSize size = textmod->GetTextSize();
268 
269  if( textmod->IsMirrored() )
270  size.x = -size.x;
271 
272  DrawGraphicText( NULL, NULL, textmod->GetTextPos(), BLACK,
273  textmod->GetShownText(), textmod->GetDrawRotation(), size,
274  textmod->GetHorizJustify(), textmod->GetVertJustify(),
275  textmod->GetThickness(), textmod->IsItalic(),
276  true, addTextSegmToPoly );
277  }
278 
279 }
280 
281 
282 // Same as function TransformGraphicShapesWithClearanceToPolygonSet but
283 // this only render text
285  PCB_LAYER_ID aLayer,
286  SHAPE_POLY_SET& aCornerBuffer,
287  int aInflateValue,
288  int aCircleToSegmentsCount,
289  double aCorrectionFactor,
290  int aCircleToSegmentsCountForTexts ) const
291 {
292  std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert
293 
294  for( EDA_ITEM* item = GraphicalItemsList(); item != NULL; item = item->Next() )
295  {
296  switch( item->Type() )
297  {
298  case PCB_MODULE_TEXT_T:
299  {
300  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
301 
302  if( text->GetLayer() == aLayer && text->IsVisible() )
303  texts.push_back( text );
304 
305  break;
306  }
307 
308  case PCB_MODULE_EDGE_T:
309  // This function does not render this
310  break;
311 
312  default:
313  break;
314  }
315  }
316 
317  // Convert texts sur modules
318  if( Reference().GetLayer() == aLayer && Reference().IsVisible() )
319  texts.push_back( &Reference() );
320 
321  if( Value().GetLayer() == aLayer && Value().IsVisible() )
322  texts.push_back( &Value() );
323 
324  s_cornerBuffer = &aCornerBuffer;
325 
326  // To allow optimization of circles approximated by segments,
327  // aCircleToSegmentsCountForTexts, when not 0, is used.
328  // if 0 (default value) the aCircleToSegmentsCount is used
329  s_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
330  aCircleToSegmentsCountForTexts : aCircleToSegmentsCount;
331 
332  for( unsigned ii = 0; ii < texts.size(); ii++ )
333  {
334  TEXTE_MODULE *textmod = texts[ii];
335  s_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
336  wxSize size = textmod->GetTextSize();
337 
338  if( textmod->IsMirrored() )
339  size.x = -size.x;
340 
341  DrawGraphicText( NULL, NULL, textmod->GetTextPos(), BLACK,
342  textmod->GetShownText(), textmod->GetDrawRotation(), size,
343  textmod->GetHorizJustify(), textmod->GetVertJustify(),
344  textmod->GetThickness(), textmod->IsItalic(),
345  true, addTextSegmToPoly );
346  }
347 
348 }
349 
350  /* Function TransformSolidAreasShapesToPolygonSet
351  * Convert solid areas full shapes to polygon set
352  * (the full shape is the polygon area with a thick outline)
353  * Used in 3D view
354  * Arcs (ends of segments) are approximated by segments
355  * aCornerBuffer = a buffer to store the polygons
356  * aCircleToSegmentsCount = the number of segments to approximate a circle
357  * aCorrectionFactor = the correction to apply to arcs radius to roughly
358  * keep arc radius when approximated by segments
359  */
361  SHAPE_POLY_SET& aCornerBuffer,
362  int aCircleToSegmentsCount,
363  double aCorrectionFactor ) const
364 {
365  if( GetFilledPolysList().IsEmpty() )
366  return;
367 
368  // add filled areas polygons
369  aCornerBuffer.Append( m_FilledPolysList );
370 
371  // add filled areas outlines, which are drawn with thick lines
372  for( int i = 0; i < m_FilledPolysList.OutlineCount(); i++ )
373  {
374  const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( i );
375 
376  for( int j = 0; j < path.PointCount(); j++ )
377  {
378  const VECTOR2I& a = path.CPoint( j );
379  const VECTOR2I& b = path.CPoint( j + 1 );
380 
381  TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ), wxPoint( b.x, b.y ),
382  aCircleToSegmentsCount,
383  GetMinThickness() );
384  }
385  }
386 }
387 
397  SHAPE_POLY_SET& aCornerBuffer,
398  int aClearanceValue ) const
399 {
400  if( GetText().Length() == 0 )
401  return;
402 
403  wxPoint corners[4]; // Buffer of polygon corners
404 
405  EDA_RECT rect = GetTextBox( -1 );
406  rect.Inflate( aClearanceValue );
407  corners[0].x = rect.GetOrigin().x;
408  corners[0].y = rect.GetOrigin().y;
409  corners[1].y = corners[0].y;
410  corners[1].x = rect.GetRight();
411  corners[2].x = corners[1].x;
412  corners[2].y = rect.GetBottom();
413  corners[3].y = corners[2].y;
414  corners[3].x = corners[0].x;
415 
416  aCornerBuffer.NewOutline();
417 
418  for( int ii = 0; ii < 4; ii++ )
419  {
420  // Rotate polygon
421  RotatePoint( &corners[ii].x, &corners[ii].y, GetTextPos().x, GetTextPos().y, GetTextAngle() );
422  aCornerBuffer.Append( corners[ii].x, corners[ii].y );
423  }
424 }
425 
426 
427 /* Function TransformShapeWithClearanceToPolygonSet
428  * Convert the text shape to a set of polygons (one by segment)
429  * Used in filling zones calculations and 3D view
430  * Circles and arcs are approximated by segments
431  * aCornerBuffer = SHAPE_POLY_SET to store the polygon corners
432  * aClearanceValue = the clearance around the text
433  * aCircleToSegmentsCount = the number of segments to approximate a circle
434  * aCorrectionFactor = the correction to apply to circles radius to keep
435  * clearance when the circle is approximated by segment bigger or equal
436  * to the real clearance value (usually near from 1.0)
437  */
438 
440  SHAPE_POLY_SET& aCornerBuffer,
441  int aClearanceValue,
442  int aCircleToSegmentsCount,
443  double aCorrectionFactor ) const
444 {
445  wxSize size = GetTextSize();
446 
447  if( IsMirrored() )
448  size.x = -size.x;
449 
450  s_cornerBuffer = &aCornerBuffer;
451  s_textWidth = GetThickness() + ( 2 * aClearanceValue );
452  s_textCircle2SegmentCount = aCircleToSegmentsCount;
453  COLOR4D color = COLOR4D::BLACK; // not actually used, but needed by DrawGraphicText
454 
455  if( IsMultilineAllowed() )
456  {
457  wxArrayString strings_list;
458  wxStringSplit( GetShownText(), strings_list, '\n' );
459  std::vector<wxPoint> positions;
460  positions.reserve( strings_list.Count() );
461  GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
462 
463  for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
464  {
465  wxString txt = strings_list.Item( ii );
466  DrawGraphicText( NULL, NULL, positions[ii], color,
467  txt, GetTextAngle(), size,
468  GetHorizJustify(), GetVertJustify(),
469  GetThickness(), IsItalic(),
470  true, addTextSegmToPoly );
471  }
472  }
473  else
474  {
475  DrawGraphicText( NULL, NULL, GetTextPos(), color,
476  GetShownText(), GetTextAngle(), size,
477  GetHorizJustify(), GetVertJustify(),
478  GetThickness(), IsItalic(),
479  true, addTextSegmToPoly );
480  }
481 }
482 
483 
497  int aClearanceValue,
498  int aCircleToSegmentsCount,
499  double aCorrectionFactor ) const
500 {
501  // The full width of the lines to create:
502  int linewidth = m_Width + (2 * aClearanceValue);
503 
504  switch( m_Shape )
505  {
506  case S_CIRCLE:
507  TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius(),
508  aCircleToSegmentsCount, linewidth ) ;
509  break;
510 
511  case S_ARC:
512  TransformArcToPolygon( aCornerBuffer, GetCenter(),
513  GetArcStart(), m_Angle,
514  aCircleToSegmentsCount, linewidth );
515  break;
516 
517  case S_SEGMENT:
518  TransformOvalClearanceToPolygon( aCornerBuffer, m_Start, m_End, linewidth,
519  aCircleToSegmentsCount, aCorrectionFactor );
520  break;
521 
522  case S_POLYGON:
523  if( IsPolyShapeValid() )
524  {
525  // The polygon is expected to be a simple polygon
526  // not self intersecting, no hole.
527  MODULE* module = GetParentModule(); // NULL for items not in footprints
528  double orientation = module ? module->GetOrientation() : 0.0;
529  wxPoint offset;
530 
531  if( module )
532  offset = module->GetPosition();
533 
534  // Build the polygon with the actual position and orientation:
535  std::vector< wxPoint> poly;
536  poly = BuildPolyPointsList();
537 
538  for( unsigned ii = 0; ii < poly.size(); ii++ )
539  {
540  RotatePoint( &poly[ii], orientation );
541  poly[ii] += offset;
542  }
543 
544  // Generate polygons for the outline + clearance
545  // This code is compatible with a polygon with holes linked to external outline
546  // by overlapping segments.
547 
548  // Insert the initial polygon:
549  aCornerBuffer.NewOutline();
550 
551  for( unsigned ii = 0; ii < poly.size(); ii++ )
552  aCornerBuffer.Append( poly[ii].x, poly[ii].y );
553 
554  if( linewidth ) // Add thick outlines
555  {
556  wxPoint corner1( poly[poly.size()-1] );
557 
558  for( unsigned ii = 0; ii < poly.size(); ii++ )
559  {
560  wxPoint corner2( poly[ii] );
561 
562  if( corner2 != corner1 )
563  {
565  corner1, corner2, aCircleToSegmentsCount, linewidth );
566  }
567 
568  corner1 = corner2;
569  }
570  }
571  }
572  break;
573 
574  case S_CURVE: // Bezier curve (TODO: not yet in use)
575  break;
576 
577  default:
578  break;
579  }
580 }
581 
582 
596  int aClearanceValue,
597  int aCircleToSegmentsCount,
598  double aCorrectionFactor ) const
599 {
600  switch( Type() )
601  {
602  case PCB_VIA_T:
603  {
604  int radius = (m_Width / 2) + aClearanceValue;
605  radius = KiROUND( radius * aCorrectionFactor );
606  TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aCircleToSegmentsCount );
607  }
608  break;
609 
610  default:
611  TransformOvalClearanceToPolygon( aCornerBuffer, m_Start, m_End,
612  m_Width + ( 2 * aClearanceValue),
613  aCircleToSegmentsCount,
614  aCorrectionFactor );
615  break;
616  }
617 }
618 
619 
620 /* Function TransformShapeWithClearanceToPolygon
621  * Convert the pad shape to a closed polygon
622  * Used in filling zones calculations and 3D view generation
623  * Circles and arcs are approximated by segments
624  * aCornerBuffer = a SHAPE_POLY_SET to store the polygon corners
625  * aClearanceValue = the clearance around the pad
626  * aCircleToSegmentsCount = the number of segments to approximate a circle
627  * aCorrectionFactor = the correction to apply to circles radius to keep
628  * clearance when the circle is approximated by segment bigger or equal
629  * to the real clearance value (usually near from 1.0)
630  */
632  int aClearanceValue,
633  int aCircleToSegmentsCount,
634  double aCorrectionFactor ) const
635 {
636  double angle = m_Orient;
637  int dx = (m_Size.x / 2) + aClearanceValue;
638  int dy = (m_Size.y / 2) + aClearanceValue;
639 
640  wxPoint padShapePos = ShapePos(); /* Note: for pad having a shape offset,
641  * the pad position is NOT the shape position */
642 
643  switch( GetShape() )
644  {
645  case PAD_SHAPE_CIRCLE:
646  dx = KiROUND( dx * aCorrectionFactor );
647  TransformCircleToPolygon( aCornerBuffer, padShapePos, dx,
648  aCircleToSegmentsCount );
649  break;
650 
651  case PAD_SHAPE_OVAL:
652  // An oval pad has the same shape as a segment with rounded ends
653  {
654  int width;
655  wxPoint shape_offset;
656  if( dy > dx ) // Oval pad X/Y ratio for choosing translation axis
657  {
658  shape_offset.y = dy - dx;
659  width = dx * 2;
660  }
661  else //if( dy <= dx )
662  {
663  shape_offset.x = dy - dx;
664  width = dy * 2;
665  }
666 
667  RotatePoint( &shape_offset, angle );
668  wxPoint start = padShapePos - shape_offset;
669  wxPoint end = padShapePos + shape_offset;
670  TransformOvalClearanceToPolygon( aCornerBuffer, start, end, width,
671  aCircleToSegmentsCount, aCorrectionFactor );
672  }
673  break;
674 
675  case PAD_SHAPE_TRAPEZOID:
676  case PAD_SHAPE_RECT:
677  {
678  wxPoint corners[4];
679  BuildPadPolygon( corners, wxSize( 0, 0 ), angle );
680 
681  SHAPE_POLY_SET outline;
682  outline.NewOutline();
683 
684  for( int ii = 0; ii < 4; ii++ )
685  {
686  corners[ii] += padShapePos;
687  outline.Append( corners[ii].x, corners[ii].y );
688  }
689 
690  int rounding_radius = int( aClearanceValue * aCorrectionFactor );
691  outline.Inflate( rounding_radius, aCircleToSegmentsCount );
692 
693  aCornerBuffer.Append( outline );
694  }
695  break;
696 
697  case PAD_SHAPE_ROUNDRECT:
698  {
699  SHAPE_POLY_SET outline;
700  int pad_radius = GetRoundRectCornerRadius();
701  int clearance = int( aClearanceValue * aCorrectionFactor );
702  int rounding_radius = pad_radius + clearance;
703  wxSize shapesize( m_Size );
704  shapesize.x += clearance*2;
705  shapesize.y += clearance*2;
706 
707  TransformRoundRectToPolygon( outline, padShapePos, shapesize, angle,
708  rounding_radius, aCircleToSegmentsCount );
709 
710  aCornerBuffer.Append( outline );
711  }
712  break;
713 
714  case PAD_SHAPE_CUSTOM:
715  {
716  int clearance = KiROUND( aClearanceValue * aCorrectionFactor );
717 
718  SHAPE_POLY_SET outline; // Will contain the corners in board coordinates
719  outline.Append( m_customShapeAsPolygon );
720  CustomShapeAsPolygonToBoardPosition( &outline, GetPosition(), GetOrientation() );
721  outline.Inflate( clearance, aCircleToSegmentsCount );
722  aCornerBuffer.Append( outline );
723  }
724  break;
725  }
726 }
727 
728 
729 
730 
731 
732 /*
733  * Function BuildPadShapePolygon
734  * Build the Corner list of the polygonal shape,
735  * depending on shape, extra size (clearance ...) pad and orientation
736  * Note: for Round and oval pads this function is equivalent to
737  * TransformShapeWithClearanceToPolygon, but not for other shapes
738  */
740  wxSize aInflateValue, int aSegmentsPerCircle,
741  double aCorrectionFactor ) const
742 {
743  wxPoint corners[4];
744  wxPoint padShapePos = ShapePos(); /* Note: for pad having a shape offset,
745  * the pad position is NOT the shape position */
746  switch( GetShape() )
747  {
748  case PAD_SHAPE_CIRCLE:
749  case PAD_SHAPE_OVAL:
750  case PAD_SHAPE_ROUNDRECT:
751  case PAD_SHAPE_CUSTOM:
752  TransformShapeWithClearanceToPolygon( aCornerBuffer, aInflateValue.x,
753  aSegmentsPerCircle, aCorrectionFactor );
754  break;
755 
756  case PAD_SHAPE_TRAPEZOID:
757  case PAD_SHAPE_RECT:
758  aCornerBuffer.NewOutline();
759 
760  BuildPadPolygon( corners, aInflateValue, m_Orient );
761  for( int ii = 0; ii < 4; ii++ )
762  {
763  corners[ii] += padShapePos; // Shift origin to position
764  aCornerBuffer.Append( corners[ii].x, corners[ii].y );
765  }
766 
767  break;
768  }
769 }
770 
771 /*
772  * Function BuildPadDrillShapePolygon
773  * Build the Corner list of the polygonal drill shape,
774  * depending on shape pad hole and orientation
775  * return false if the pad has no hole, true otherwise
776  */
778  int aInflateValue, int aSegmentsPerCircle ) const
779 {
780  wxSize drillsize = GetDrillSize();
781 
782  if( !drillsize.x || !drillsize.y )
783  return false;
784 
785  if( drillsize.x == drillsize.y ) // usual round hole
786  {
787  TransformCircleToPolygon( aCornerBuffer, GetPosition(),
788  (drillsize.x / 2) + aInflateValue, aSegmentsPerCircle );
789  }
790  else // Oblong hole
791  {
792  wxPoint start, end;
793  int width;
794 
795  GetOblongDrillGeometry( start, end, width );
796 
797  width += aInflateValue * 2;
798 
800  GetPosition() + start, GetPosition() + end, aSegmentsPerCircle, width );
801  }
802 
803  return true;
804 }
805 
820 /* thermal reliefs are created as 4 polygons.
821  * each corner of a polygon if calculated for a pad at position 0, 0, orient 0,
822  * and then moved and rotated acroding to the pad position and orientation
823  */
824 
825 /*
826  * Note 1: polygons are drawm using outlines witk a thickness = aMinThicknessValue
827  * so shapes must take in account this outline thickness
828  *
829  * Note 2:
830  * Trapezoidal pads are not considered here because they are very special case
831  * and are used in microwave applications and they *DO NOT* have a thermal relief that
832  * change the shape by creating stubs and destroy their properties.
833  */
835  const D_PAD& aPad,
836  int aThermalGap,
837  int aCopperThickness,
838  int aMinThicknessValue,
839  int aCircleToSegmentsCount,
840  double aCorrectionFactor,
841  double aThermalRot )
842 {
843  wxPoint corner, corner_end;
844  wxPoint padShapePos = aPad.ShapePos(); // Note: for pad having a shape offset,
845  // the pad position is NOT the shape position
846  wxSize copper_thickness;
847 
848  double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
849 
850  /* Keep in account the polygon outline thickness
851  * aThermalGap must be increased by aMinThicknessValue/2 because drawing external outline
852  * with a thickness of aMinThicknessValue will reduce gap by aMinThicknessValue/2
853  */
854  aThermalGap += aMinThicknessValue / 2;
855 
856  /* Keep in account the polygon outline thickness
857  * copper_thickness must be decreased by aMinThicknessValue because drawing outlines
858  * with a thickness of aMinThicknessValue will increase real thickness by aMinThicknessValue
859  */
860  aCopperThickness -= aMinThicknessValue;
861 
862  if( aCopperThickness < 0 )
863  aCopperThickness = 0;
864 
865  int dx = aPad.GetSize().x / 2;
866  int dy = aPad.GetSize().y / 2;
867 
868  copper_thickness.x = std::min( dx, aCopperThickness );
869  copper_thickness.y = std::min( dy, aCopperThickness );
870 
871  switch( aPad.GetShape() )
872  {
873  case PAD_SHAPE_CIRCLE: // Add 4 similar holes
874  {
875  /* we create 4 copper holes and put them in position 1, 2, 3 and 4
876  * here is the area of the rectangular pad + its thermal gap
877  * the 4 copper holes remove the copper in order to create the thermal gap
878  * 4 ------ 1
879  * | |
880  * | |
881  * | |
882  * | |
883  * 3 ------ 2
884  * holes 2, 3, 4 are the same as hole 1, rotated 90, 180, 270 deg
885  */
886 
887  // Build the hole pattern, for the hole in the X >0, Y > 0 plane:
888  // The pattern roughtly is a 90 deg arc pie
889  std::vector <wxPoint> corners_buffer;
890 
891  // Radius of outer arcs of the shape corrected for arc approximation by lines
892  int outer_radius = KiROUND( (dx + aThermalGap) * aCorrectionFactor );
893 
894  // Crosspoint of thermal spoke sides, the first point of polygon buffer
895  corners_buffer.push_back( wxPoint( copper_thickness.x / 2, copper_thickness.y / 2 ) );
896 
897  // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side
898  // and first seg of arc approx
899  corner.x = copper_thickness.x / 2;
900  int y = outer_radius - (aThermalGap / 4);
901  corner.y = KiROUND( sqrt( ( (double) y * y - (double) corner.x * corner.x ) ) );
902 
903  if( aThermalRot != 0 )
904  corners_buffer.push_back( corner );
905 
906  // calculate the starting point of the outter arc
907  corner.x = copper_thickness.x / 2;
908 
909  corner.y = KiROUND( sqrt( ( (double) outer_radius * outer_radius ) -
910  ( (double) corner.x * corner.x ) ) );
911  RotatePoint( &corner, 90 ); // 9 degrees is the spoke fillet size
912 
913  // calculate the ending point of the outter arc
914  corner_end.x = corner.y;
915  corner_end.y = corner.x;
916 
917  // calculate intermediate points (y coordinate from corner.y to corner_end.y
918  while( (corner.y > corner_end.y) && (corner.x < corner_end.x) )
919  {
920  corners_buffer.push_back( corner );
921  RotatePoint( &corner, delta );
922  }
923 
924  corners_buffer.push_back( corner_end );
925 
926  /* add an intermediate point, to avoid angles < 90 deg between last arc approx line
927  * and radius line
928  */
929  corner.x = corners_buffer[1].y;
930  corner.y = corners_buffer[1].x;
931  corners_buffer.push_back( corner );
932 
933  // Now, add the 4 holes ( each is the pattern, rotated by 0, 90, 180 and 270 deg
934  // aThermalRot = 450 (45.0 degrees orientation) work fine.
935  double angle_pad = aPad.GetOrientation(); // Pad orientation
936  double th_angle = aThermalRot;
937 
938  for( unsigned ihole = 0; ihole < 4; ihole++ )
939  {
940  aCornerBuffer.NewOutline();
941 
942  for( unsigned ii = 0; ii < corners_buffer.size(); ii++ )
943  {
944  corner = corners_buffer[ii];
945  RotatePoint( &corner, th_angle + angle_pad ); // Rotate by segment angle and pad orientation
946  corner += padShapePos;
947  aCornerBuffer.Append( corner.x, corner.y );
948  }
949 
950  th_angle += 900; // Note: th_angle in in 0.1 deg.
951  }
952  }
953  break;
954 
955  case PAD_SHAPE_OVAL:
956  {
957  // Oval pad support along the lines of round and rectangular pads
958  std::vector <wxPoint> corners_buffer; // Polygon buffer as vector
959 
960  dx = (aPad.GetSize().x / 2) + aThermalGap; // Cutout radius x
961  dy = (aPad.GetSize().y / 2) + aThermalGap; // Cutout radius y
962 
963  wxPoint shape_offset;
964 
965  // We want to calculate an oval shape with dx > dy.
966  // if this is not the case, exchange dx and dy, and rotate the shape 90 deg.
967  int supp_angle = 0;
968 
969  if( dx < dy )
970  {
971  std::swap( dx, dy );
972  supp_angle = 900;
973  std::swap( copper_thickness.x, copper_thickness.y );
974  }
975 
976  int deltasize = dx - dy; // = distance between shape position and the 2 demi-circle ends centre
977  // here we have dx > dy
978  // Radius of outer arcs of the shape:
979  int outer_radius = dy; // The radius of the outer arc is radius end + aThermalGap
980 
981  // Some coordinate fiddling, depending on the shape offset direction
982  shape_offset = wxPoint( deltasize, 0 );
983 
984  // Crosspoint of thermal spoke sides, the first point of polygon buffer
985  corner.x = copper_thickness.x / 2;
986  corner.y = copper_thickness.y / 2;
987  corners_buffer.push_back( corner );
988 
989  // Arc start point calculation, the intersecting point of cutout arc and thermal spoke edge
990  // If copper thickness is more than shape offset, we need to calculate arc intercept point.
991  if( copper_thickness.x > deltasize )
992  {
993  corner.x = copper_thickness.x / 2;
994  corner.y = KiROUND( sqrt( ( (double) outer_radius * outer_radius ) -
995  ( (double) ( corner.x - delta ) * ( corner.x - deltasize ) ) ) );
996  corner.x -= deltasize;
997 
998  /* creates an intermediate point, to have a > 90 deg angle
999  * between the side and the first segment of arc approximation
1000  */
1001  wxPoint intpoint = corner;
1002  intpoint.y -= aThermalGap / 4;
1003  corners_buffer.push_back( intpoint + shape_offset );
1004  RotatePoint( &corner, 90 ); // 9 degrees of thermal fillet
1005  }
1006  else
1007  {
1008  corner.x = copper_thickness.x / 2;
1009  corner.y = outer_radius;
1010  corners_buffer.push_back( corner );
1011  }
1012 
1013  // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side
1014  // and first seg of arc approx
1015  wxPoint last_corner;
1016  last_corner.y = copper_thickness.y / 2;
1017  int px = outer_radius - (aThermalGap / 4);
1018  last_corner.x =
1019  KiROUND( sqrt( ( ( (double) px * px ) - (double) last_corner.y * last_corner.y ) ) );
1020 
1021  // Arc stop point calculation, the intersecting point of cutout arc and thermal spoke edge
1022  corner_end.y = copper_thickness.y / 2;
1023  corner_end.x =
1024  KiROUND( sqrt( ( (double) outer_radius *
1025  outer_radius ) - ( (double) corner_end.y * corner_end.y ) ) );
1026  RotatePoint( &corner_end, -90 ); // 9 degrees of thermal fillet
1027 
1028  // calculate intermediate arc points till limit is reached
1029  while( (corner.y > corner_end.y) && (corner.x < corner_end.x) )
1030  {
1031  corners_buffer.push_back( corner + shape_offset );
1032  RotatePoint( &corner, delta );
1033  }
1034 
1035  //corners_buffer.push_back(corner + shape_offset); // TODO: about one mil geometry error forms somewhere.
1036  corners_buffer.push_back( corner_end + shape_offset );
1037  corners_buffer.push_back( last_corner + shape_offset ); // Enabling the line above shows intersection point.
1038 
1039  /* Create 2 holes, rotated by pad rotation.
1040  */
1041  double angle = aPad.GetOrientation() + supp_angle;
1042 
1043  for( int irect = 0; irect < 2; irect++ )
1044  {
1045  aCornerBuffer.NewOutline();
1046  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1047  {
1048  wxPoint cpos = corners_buffer[ic];
1049  RotatePoint( &cpos, angle );
1050  cpos += padShapePos;
1051  aCornerBuffer.Append( cpos.x, cpos.y );
1052  }
1053 
1054  angle = AddAngles( angle, 1800 ); // this is calculate hole 3
1055  }
1056 
1057  // Create holes, that are the mirrored from the previous holes
1058  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1059  {
1060  wxPoint swap = corners_buffer[ic];
1061  swap.x = -swap.x;
1062  corners_buffer[ic] = swap;
1063  }
1064 
1065  // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
1066  angle = aPad.GetOrientation() + supp_angle;
1067 
1068  for( int irect = 0; irect < 2; irect++ )
1069  {
1070  aCornerBuffer.NewOutline();
1071 
1072  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1073  {
1074  wxPoint cpos = corners_buffer[ic];
1075  RotatePoint( &cpos, angle );
1076  cpos += padShapePos;
1077  aCornerBuffer.Append( cpos.x, cpos.y );
1078  }
1079 
1080  angle = AddAngles( angle, 1800 );
1081  }
1082  }
1083  break;
1084 
1085  case PAD_SHAPE_ROUNDRECT: // thermal shape is the same for round rect and rect.
1086  case PAD_SHAPE_RECT:
1087  {
1088  /* we create 4 copper holes and put them in position 1, 2, 3 and 4
1089  * here is the area of the rectangular pad + its thermal gap
1090  * the 4 copper holes remove the copper in order to create the thermal gap
1091  * 4 ------ 1
1092  * | |
1093  * | |
1094  * | |
1095  * | |
1096  * 3 ------ 2
1097  * hole 3 is the same as hole 1, rotated 180 deg
1098  * hole 4 is the same as hole 2, rotated 180 deg and is the same as hole 1, mirrored
1099  */
1100 
1101  // First, create a rectangular hole for position 1 :
1102  // 2 ------- 3
1103  // | |
1104  // | |
1105  // | |
1106  // 1 -------4
1107 
1108  // Modified rectangles with one corner rounded. TODO: merging with oval thermals
1109  // and possibly round too.
1110 
1111  std::vector <wxPoint> corners_buffer; // Polygon buffer as vector
1112 
1113  dx = (aPad.GetSize().x / 2) + aThermalGap; // Cutout radius x
1114  dy = (aPad.GetSize().y / 2) + aThermalGap; // Cutout radius y
1115 
1116  // The first point of polygon buffer is left lower corner, second the crosspoint of
1117  // thermal spoke sides, the third is upper right corner and the rest are rounding
1118  // vertices going anticlockwise. Note the inveted Y-axis in CG.
1119  corners_buffer.push_back( wxPoint( -dx, -(aThermalGap / 4 + copper_thickness.y / 2) ) ); // Adds small miters to zone
1120  corners_buffer.push_back( wxPoint( -(dx - aThermalGap / 4), -copper_thickness.y / 2 ) ); // fill and spoke corner
1121  corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -copper_thickness.y / 2 ) );
1122  corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -(dy - aThermalGap / 4) ) );
1123  corners_buffer.push_back( wxPoint( -(aThermalGap / 4 + copper_thickness.x / 2), -dy ) );
1124 
1125  double angle = aPad.GetOrientation();
1126  int rounding_radius = KiROUND( aThermalGap * aCorrectionFactor ); // Corner rounding radius
1127 
1128  for( int i = 0; i < aCircleToSegmentsCount / 4 + 1; i++ )
1129  {
1130  wxPoint corner_position = wxPoint( 0, -rounding_radius );
1131 
1132  // Start at half increment offset
1133  RotatePoint( &corner_position, 1800.0 / aCircleToSegmentsCount );
1134  double angle_pg = i * delta;
1135 
1136  RotatePoint( &corner_position, angle_pg ); // Rounding vector rotation
1137  corner_position -= aPad.GetSize() / 2; // Rounding vector + Pad corner offset
1138 
1139  corners_buffer.push_back( wxPoint( corner_position.x, corner_position.y ) );
1140  }
1141 
1142  for( int irect = 0; irect < 2; irect++ )
1143  {
1144  aCornerBuffer.NewOutline();
1145 
1146  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1147  {
1148  wxPoint cpos = corners_buffer[ic];
1149  RotatePoint( &cpos, angle ); // Rotate according to module orientation
1150  cpos += padShapePos; // Shift origin to position
1151  aCornerBuffer.Append( cpos.x, cpos.y );
1152  }
1153 
1154  angle = AddAngles( angle, 1800 ); // this is calculate hole 3
1155  }
1156 
1157  // Create holes, that are the mirrored from the previous holes
1158  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1159  {
1160  wxPoint swap = corners_buffer[ic];
1161  swap.x = -swap.x;
1162  corners_buffer[ic] = swap;
1163  }
1164 
1165  // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
1166  for( int irect = 0; irect < 2; irect++ )
1167  {
1168  aCornerBuffer.NewOutline();
1169 
1170  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1171  {
1172  wxPoint cpos = corners_buffer[ic];
1173  RotatePoint( &cpos, angle );
1174  cpos += padShapePos;
1175  aCornerBuffer.Append( cpos.x, cpos.y );
1176  }
1177 
1178  angle = AddAngles( angle, 1800 );
1179  }
1180  }
1181  break;
1182 
1183  case PAD_SHAPE_TRAPEZOID:
1184  {
1185  SHAPE_POLY_SET antipad; // The full antipad area
1186 
1187  // We need a length to build the stubs of the thermal reliefs
1188  // the value is not very important. The pad bounding box gives a reasonable value
1189  EDA_RECT bbox = aPad.GetBoundingBox();
1190  int stub_len = std::max( bbox.GetWidth(), bbox.GetHeight() );
1191 
1192  aPad.TransformShapeWithClearanceToPolygon( antipad, aThermalGap,
1193  aCircleToSegmentsCount, aCorrectionFactor );
1194 
1195  SHAPE_POLY_SET stub; // A basic stub ( a rectangle)
1196  SHAPE_POLY_SET stubs; // the full stubs shape
1197 
1198 
1199  // We now substract the stubs (connections to the copper zone)
1200  //ClipperLib::Clipper clip_engine;
1201  // Prepare a clipping transform
1202  //clip_engine.AddPath( antipad, ClipperLib::ptSubject, true );
1203 
1204  // Create stubs and add them to clipper engine
1205  wxPoint stubBuffer[4];
1206  stubBuffer[0].x = stub_len;
1207  stubBuffer[0].y = copper_thickness.y/2;
1208  stubBuffer[1] = stubBuffer[0];
1209  stubBuffer[1].y = -copper_thickness.y/2;
1210  stubBuffer[2] = stubBuffer[1];
1211  stubBuffer[2].x = -stub_len;
1212  stubBuffer[3] = stubBuffer[2];
1213  stubBuffer[3].y = copper_thickness.y/2;
1214 
1215  stub.NewOutline();
1216 
1217  for( unsigned ii = 0; ii < DIM( stubBuffer ); ii++ )
1218  {
1219  wxPoint cpos = stubBuffer[ii];
1220  RotatePoint( &cpos, aPad.GetOrientation() );
1221  cpos += padShapePos;
1222  stub.Append( cpos.x, cpos.y );
1223  }
1224 
1225  stubs.Append( stub );
1226 
1227  stubBuffer[0].y = stub_len;
1228  stubBuffer[0].x = copper_thickness.x/2;
1229  stubBuffer[1] = stubBuffer[0];
1230  stubBuffer[1].x = -copper_thickness.x/2;
1231  stubBuffer[2] = stubBuffer[1];
1232  stubBuffer[2].y = -stub_len;
1233  stubBuffer[3] = stubBuffer[2];
1234  stubBuffer[3].x = copper_thickness.x/2;
1235 
1236  stub.RemoveAllContours();
1237  stub.NewOutline();
1238 
1239  for( unsigned ii = 0; ii < DIM( stubBuffer ); ii++ )
1240  {
1241  wxPoint cpos = stubBuffer[ii];
1242  RotatePoint( &cpos, aPad.GetOrientation() );
1243  cpos += padShapePos;
1244  stub.Append( cpos.x, cpos.y );
1245  }
1246 
1247  stubs.Append( stub );
1249 
1250  antipad.BooleanSubtract( stubs, SHAPE_POLY_SET::PM_FAST );
1251  aCornerBuffer.Append( antipad );
1252 
1253  break;
1254  }
1255 
1256  default:
1257  ;
1258  }
1259 }
1260 
1262  int aClearanceValue,
1263  int aCircleToSegmentsCount,
1264  double aCorrectionFactor ) const
1265 {
1266  aCornerBuffer = m_FilledPolysList;
1268 }
void TransformRoundedEndsSegmentToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aCircleToSegmentsCount, int aWidth)
Function TransformRoundedEndsSegmentToPolygon convert a segment with rounded ends to a polygon Conver...
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Function wxStringSplit splits aString to a string list separated at aSplitter.
Definition: common.cpp:137
KICAD_T Type() const
Function Type()
Definition: base_struct.h:227
#define DIM(x)
of elements in an array
Definition: macros.h:98
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
const wxPoint GetOrigin() const
Definition: eda_rect.h:112
static SHAPE_POLY_SET * s_cornerBuffer
double GetDrawRotation() const
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:398
TEXTE_PCB class definition.
const wxPoint & GetTextPos() const
Definition: eda_text.h:222
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
bool IsItalic() const
Definition: eda_text.h:168
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
virtual const wxPoint GetPosition() const override
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void TransformCircleToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCenter, int aRadius, int aCircleToSegmentsCount)
Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines...
int PointCount() const
Function PointCount()
void TransformGraphicShapesWithClearanceToPolygonSet(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, int aCircleToSegmentsCount, double aCorrectionFactor, int aCircleToSegmentsCountForTexts=0, bool aIncludeText=true) const
function TransformGraphicShapesWithClearanceToPolygonSet generate shapes of graphic items (outlines) ...
Class BOARD to handle a board.
void TransformRoundRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, int aCircleToSegmentsCount)
Function TransformRoundRectToPolygon convert a rectangle with rounded corners to a polygon Convert ar...
int color
Definition: DXF_plotter.cpp:62
polygon (not yet used for tracks, but could be in microwave apps)
MODULE * Next() const
Definition: class_module.h:120
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:171
int GetHeight() const
Definition: eda_rect.h:118
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
void CreateThermalReliefPadPolygon(SHAPE_POLY_SET &aCornerBuffer, const D_PAD &aPad, int aThermalGap, int aCopperThickness, int aMinThicknessValue, int aCircleToSegmentsCount, double aCorrectionFactor, double aThermalRot)
Function CreateThermalReliefPadPolygon Add holes around a pad to create a thermal relief copper thick...
Classes to handle copper zones.
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:381
usual segment : line with rounded ends
EDA_ITEM * Next() const
Definition: base_struct.h:235
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
void TransformOvalClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aWidth, int aCircleToSegmentsCount, double aCorrectionFactor)
convert a oblong shape to a polygon, using multiple segments It is similar to TransformRoundedEndsSeg...
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
virtual wxString GetShownText() const override
Returns the string actually shown after processing of the base text.
virtual void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:188
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
static const int delta[8][2]
Definition: solve.cpp:112
Functions relatives to tracks, vias and segments used to fill zones.
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:152
wxSize GetTextSize(const wxString &aSingleLine, wxWindow *aWindow)
Function GetTextSize returns the size of aSingleLine of text when it is rendered in aWindow using wha...
Definition: common.cpp:93
void TransformSolidAreasShapesToPolygonSet(SHAPE_POLY_SET &aCornerBuffer, int aCircleToSegmentsCount, double aCorrectionFactor) const
Function TransformSolidAreasShapesToPolygonSet Convert solid areas full shapes to polygon set (the fu...
virtual const wxPoint GetCenter() const
Function GetCenter()
BOARD_ITEM * Next() const
PCB_LAYER_ID
A quick note on layer IDs:
void TransformShapeWithClearanceToPolygonSet(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const
Function TransformShapeWithClearanceToPolygonSet Convert the text shape to a set of polygons (one by ...
void Inflate(int aFactor, int aCircleSegmentsCount)
Performs outline inflation/deflation, using round corners.
void TransformBoundingBoxWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue) const
Function TransformBoundingBoxWithClearanceToPolygon Convert the text bounding box to a rectangular po...
T AddAngles(T a1, T2 a2)
Add two angles (keeping the result normalized). T2 is here.
Definition: trigo.h:267
double GetOrientation() const
Definition: class_module.h:186
Class SHAPE_POLY_SET.
int GetSolderMaskMargin() const
Function GetSolderMaskMargin.
Definition: class_pad.cpp:576
bool IsEmpty() const
Definition: class_board.h:268
Arcs (with rounded ends)
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const override
Function TransformShapeWithClearanceToPolygon Convert the track shape to a closed polygon Used in fil...
D_PAD * Next() const
Definition: class_pad.h:160
const wxSize & GetSize() const
Definition: class_pad.h:269
DLIST< BOARD_ITEM > m_Drawings
Definition: class_board.h:241
void ConvertBrdLayerToPolygonalContours(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aOutlines)
Function ConvertBrdLayerToPolygonalContours Build a set of polygons which are the outlines of copper ...
void Simplify(POLYGON_MODE aFastMode)
Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFast...
wxString GetText(GRAPHIC_PINSHAPE shape)
Definition: pin_shape.cpp:33
void TransformGraphicTextWithClearanceToPolygonSet(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, int aCircleToSegmentsCount, double aCorrectionFactor, int aCircleToSegmentsCountForTexts=0) const
TransformGraphicTextWithClearanceToPolygonSet This function is the same as TransformGraphicShapesWith...
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const override
Function TransformShapeWithClearanceToPolygon Convert the pad shape to a closed polygon Used in filli...
int GetBottom() const
Definition: eda_rect.h:122
Bezier Curve.
int GetRight() const
Definition: eda_rect.h:119
void TransformPadsShapesWithClearanceToPolygon(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, int aCircleToSegmentsCount, double aCorrectionFactor, bool aSkipNPTHPadsWihNoCopper=false) const
function TransformPadsShapesWithClearanceToPolygon generate pads shapes on layer aLayer as polygons...
int NewOutline()
Creates a new empty polygon in the set and returns its index
Pad object description.
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const override
Function TransformShapeWithClearanceToPolygon Convert the track shape to a closed polygon Used in fil...
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:189
void TransformRingToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCentre, int aRadius, int aCircleToSegmentsCount, int aWidth)
Function TransformRingToPolygon Creates a polygon from a ring Convert arcs to multiple straight segme...
void TransformArcToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCentre, wxPoint aStart, double aArcAngle, int aCircleToSegmentsCount, int aWidth)
Function TransformArcToPolygon Creates a polygon from an Arc Convert arcs to multiple straight segmen...
TRACK * Next() const
Definition: class_track.h:99
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
Class to handle a graphic segment.
#define max(a, b)
Definition: auxiliary.h:86
bool IsMirrored() const
Definition: eda_text.h:177
DLIST< MODULE > m_Modules
Definition: class_board.h:245
Class SHAPE_LINE_CHAIN.
bool IsVisible() const
Definition: eda_text.h:174
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:375
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
wxSize GetSolderPasteMargin() const
Function GetSolderPasteMargin.
Definition: class_pad.cpp:609
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:180
int GetWidth() const
Definition: eda_rect.h:117
void BuildPadShapePolygon(SHAPE_POLY_SET &aCornerBuffer, wxSize aInflateValue, int aSegmentsPerCircle, double aCorrectionFactor) const
Function BuildPadShapePolygon Build the Corner list of the polygonal shape, depending on shape...
wxPoint ShapePos() const
Definition: class_pad.cpp:499
void DrawGraphicText(EDA_RECT *aClipBox, 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), PLOTTER *aPlotter)
Function DrawGraphicText Draw a graphic text (like module texts)
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
static int s_textCircle2SegmentCount
DLIST< TRACK > m_Track
Definition: class_board.h:246
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset difference For aFastMode meaning, see function booleanOp ...
Module description (excepted pads)
Definition: colors.h:45
const wxSize & GetTextSize() const
Definition: eda_text.h:213
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const override
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: class_pad.h:637
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
bool BuildPadDrillShapePolygon(SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, int aSegmentsPerCircle) const
Function BuildPadDrillShapePolygon Build the Corner list of the polygonal drill shape, depending on shape pad hole and orientation.
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
const wxPoint GetPosition() const override
Definition: class_module.h:181
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: class_pad.cpp:198
const wxPoint & GetOffset() const
Definition: class_pad.h:278
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
static void addTextSegmToPoly(int x0, int y0, int xf, int yf)
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) ...
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39