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 <drawtxt.h>
37 #include <pcbnew.h>
38 #include <wxPcbStruct.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 = Pads();
137 
138  wxSize margin;
139  for( ; pad != NULL; pad = pad->Next() )
140  {
141  if( !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 ) const
210 {
211  std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert
212  EDGE_MODULE* outline;
213 
214  for( EDA_ITEM* item = GraphicalItems(); item != NULL; item = item->Next() )
215  {
216  switch( item->Type() )
217  {
218  case PCB_MODULE_TEXT_T:
219  {
220  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
221 
222  if( text->GetLayer() == aLayer && text->IsVisible() )
223  texts.push_back( text );
224 
225  break;
226  }
227 
228  case PCB_MODULE_EDGE_T:
229  outline = (EDGE_MODULE*) item;
230 
231  if( outline->GetLayer() != aLayer )
232  break;
233 
234  outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, 0,
235  aCircleToSegmentsCount, aCorrectionFactor );
236  break;
237 
238  default:
239  break;
240  }
241  }
242 
243  // Convert texts sur modules
244  if( Reference().GetLayer() == aLayer && Reference().IsVisible() )
245  texts.push_back( &Reference() );
246 
247  if( Value().GetLayer() == aLayer && Value().IsVisible() )
248  texts.push_back( &Value() );
249 
250  s_cornerBuffer = &aCornerBuffer;
251 
252  // To allow optimization of circles approximated by segments,
253  // aCircleToSegmentsCountForTexts, when not 0, is used.
254  // if 0 (default value) the aCircleToSegmentsCount is used
255  s_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
256  aCircleToSegmentsCountForTexts : aCircleToSegmentsCount;
257 
258  for( unsigned ii = 0; ii < texts.size(); ii++ )
259  {
260  TEXTE_MODULE *textmod = texts[ii];
261  s_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
262  wxSize size = textmod->GetTextSize();
263 
264  if( textmod->IsMirrored() )
265  size.x = -size.x;
266 
267  DrawGraphicText( NULL, NULL, textmod->GetTextPos(), BLACK,
268  textmod->GetShownText(), textmod->GetDrawRotation(), size,
269  textmod->GetHorizJustify(), textmod->GetVertJustify(),
270  textmod->GetThickness(), textmod->IsItalic(),
271  true, addTextSegmToPoly );
272  }
273 
274 }
275 
276 
277 // Same as function TransformGraphicShapesWithClearanceToPolygonSet but
278 // this only render text
280  PCB_LAYER_ID aLayer,
281  SHAPE_POLY_SET& aCornerBuffer,
282  int aInflateValue,
283  int aCircleToSegmentsCount,
284  double aCorrectionFactor,
285  int aCircleToSegmentsCountForTexts ) const
286 {
287  std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert
288 
289  for( EDA_ITEM* item = GraphicalItems(); item != NULL; item = item->Next() )
290  {
291  switch( item->Type() )
292  {
293  case PCB_MODULE_TEXT_T:
294  {
295  TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
296 
297  if( text->GetLayer() == aLayer && text->IsVisible() )
298  texts.push_back( text );
299 
300  break;
301  }
302 
303  case PCB_MODULE_EDGE_T:
304  // This function does not render this
305  break;
306 
307  default:
308  break;
309  }
310  }
311 
312  // Convert texts sur modules
313  if( Reference().GetLayer() == aLayer && Reference().IsVisible() )
314  texts.push_back( &Reference() );
315 
316  if( Value().GetLayer() == aLayer && Value().IsVisible() )
317  texts.push_back( &Value() );
318 
319  s_cornerBuffer = &aCornerBuffer;
320 
321  // To allow optimization of circles approximated by segments,
322  // aCircleToSegmentsCountForTexts, when not 0, is used.
323  // if 0 (default value) the aCircleToSegmentsCount is used
324  s_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
325  aCircleToSegmentsCountForTexts : aCircleToSegmentsCount;
326 
327  for( unsigned ii = 0; ii < texts.size(); ii++ )
328  {
329  TEXTE_MODULE *textmod = texts[ii];
330  s_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
331  wxSize size = textmod->GetTextSize();
332 
333  if( textmod->IsMirrored() )
334  size.x = -size.x;
335 
336  DrawGraphicText( NULL, NULL, textmod->GetTextPos(), BLACK,
337  textmod->GetShownText(), textmod->GetDrawRotation(), size,
338  textmod->GetHorizJustify(), textmod->GetVertJustify(),
339  textmod->GetThickness(), textmod->IsItalic(),
340  true, addTextSegmToPoly );
341  }
342 
343 }
344 
345  /* Function TransformSolidAreasShapesToPolygonSet
346  * Convert solid areas full shapes to polygon set
347  * (the full shape is the polygon area with a thick outline)
348  * Used in 3D view
349  * Arcs (ends of segments) are approximated by segments
350  * aCornerBuffer = a buffer to store the polygons
351  * aCircleToSegmentsCount = the number of segments to approximate a circle
352  * aCorrectionFactor = the correction to apply to arcs radius to roughly
353  * keep arc radius when approximated by segments
354  */
356  SHAPE_POLY_SET& aCornerBuffer,
357  int aCircleToSegmentsCount,
358  double aCorrectionFactor ) const
359 {
360  if( GetFilledPolysList().IsEmpty() )
361  return;
362 
363  // add filled areas polygons
364  aCornerBuffer.Append( m_FilledPolysList );
365 
366  // add filled areas outlines, which are drawn with thick lines
367  for( int i = 0; i < m_FilledPolysList.OutlineCount(); i++ )
368  {
369  const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( i );
370 
371  for( int j = 0; j < path.PointCount(); j++ )
372  {
373  const VECTOR2I& a = path.CPoint( j );
374  const VECTOR2I& b = path.CPoint( j + 1 );
375 
376  TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ), wxPoint( b.x, b.y ),
377  aCircleToSegmentsCount,
378  GetMinThickness() );
379  }
380  }
381 }
382 
392  SHAPE_POLY_SET& aCornerBuffer,
393  int aClearanceValue ) const
394 {
395  if( GetText().Length() == 0 )
396  return;
397 
398  wxPoint corners[4]; // Buffer of polygon corners
399 
400  EDA_RECT rect = GetTextBox( -1 );
401  rect.Inflate( aClearanceValue );
402  corners[0].x = rect.GetOrigin().x;
403  corners[0].y = rect.GetOrigin().y;
404  corners[1].y = corners[0].y;
405  corners[1].x = rect.GetRight();
406  corners[2].x = corners[1].x;
407  corners[2].y = rect.GetBottom();
408  corners[3].y = corners[2].y;
409  corners[3].x = corners[0].x;
410 
411  aCornerBuffer.NewOutline();
412 
413  for( int ii = 0; ii < 4; ii++ )
414  {
415  // Rotate polygon
416  RotatePoint( &corners[ii].x, &corners[ii].y, GetTextPos().x, GetTextPos().y, GetTextAngle() );
417  aCornerBuffer.Append( corners[ii].x, corners[ii].y );
418  }
419 }
420 
421 
422 /* Function TransformShapeWithClearanceToPolygonSet
423  * Convert the text shape to a set of polygons (one by segment)
424  * Used in filling zones calculations and 3D view
425  * Circles and arcs are approximated by segments
426  * aCornerBuffer = SHAPE_POLY_SET to store the polygon corners
427  * aClearanceValue = the clearance around the text
428  * aCircleToSegmentsCount = the number of segments to approximate a circle
429  * aCorrectionFactor = the correction to apply to circles radius to keep
430  * clearance when the circle is approximated by segment bigger or equal
431  * to the real clearance value (usually near from 1.0)
432  */
433 
435  SHAPE_POLY_SET& aCornerBuffer,
436  int aClearanceValue,
437  int aCircleToSegmentsCount,
438  double aCorrectionFactor ) const
439 {
440  wxSize size = GetTextSize();
441 
442  if( IsMirrored() )
443  size.x = -size.x;
444 
445  s_cornerBuffer = &aCornerBuffer;
446  s_textWidth = GetThickness() + ( 2 * aClearanceValue );
447  s_textCircle2SegmentCount = aCircleToSegmentsCount;
448  COLOR4D color = COLOR4D::BLACK; // not actually used, but needed by DrawGraphicText
449 
450  if( IsMultilineAllowed() )
451  {
452  wxArrayString strings_list;
453  wxStringSplit( GetShownText(), strings_list, '\n' );
454  std::vector<wxPoint> positions;
455  positions.reserve( strings_list.Count() );
456  GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
457 
458  for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
459  {
460  wxString txt = strings_list.Item( ii );
461  DrawGraphicText( NULL, NULL, positions[ii], color,
462  txt, GetTextAngle(), size,
464  GetThickness(), IsItalic(),
465  true, addTextSegmToPoly );
466  }
467  }
468  else
469  {
470  DrawGraphicText( NULL, NULL, GetTextPos(), color,
471  GetShownText(), GetTextAngle(), size,
473  GetThickness(), IsItalic(),
474  true, addTextSegmToPoly );
475  }
476 }
477 
478 
492  int aClearanceValue,
493  int aCircleToSegmentsCount,
494  double aCorrectionFactor ) const
495 {
496  // The full width of the lines to create:
497  int linewidth = m_Width + (2 * aClearanceValue);
498 
499  switch( m_Shape )
500  {
501  case S_CIRCLE:
502  TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius(),
503  aCircleToSegmentsCount, linewidth ) ;
504  break;
505 
506  case S_ARC:
507  TransformArcToPolygon( aCornerBuffer, GetCenter(),
508  GetArcStart(), m_Angle,
509  aCircleToSegmentsCount, linewidth );
510  break;
511 
512  case S_SEGMENT:
514  aCircleToSegmentsCount, linewidth );
515  break;
516 
517  case S_POLYGON:
518  if ( GetPolyPoints().size() < 2 )
519  break; // Malformed polygon.
520  {
521  // The polygon is expected to be a simple polygon
522  // not self intersecting, no hole.
523  MODULE* module = GetParentModule(); // NULL for items not in footprints
524  double orientation = module ? module->GetOrientation() : 0.0;
525 
526  // Build the polygon with the actual position and orientation:
527  std::vector< wxPoint> poly;
528  poly = GetPolyPoints();
529 
530  for( unsigned ii = 0; ii < poly.size(); ii++ )
531  {
532  RotatePoint( &poly[ii], orientation );
533  poly[ii] += GetPosition();
534  }
535 
536  // Generate polygons for the outline + clearance
537  // This code is compatible with a polygon with holes linked to external outline
538  // by overlapping segments.
539 
540  // Insert the initial polygon:
541  aCornerBuffer.NewOutline();
542 
543  for( unsigned ii = 0; ii < poly.size(); ii++ )
544  aCornerBuffer.Append( poly[ii].x, poly[ii].y );
545 
546  if( linewidth ) // Add thick outlines
547  {
548  CPolyPt corner1( poly[poly.size()-1] );
549 
550  for( unsigned ii = 0; ii < poly.size(); ii++ )
551  {
552  CPolyPt corner2( poly[ii] );
553 
554  if( corner2 != corner1 )
555  {
557  corner1, corner2, aCircleToSegmentsCount, linewidth );
558  }
559 
560  corner1 = corner2;
561  }
562  }
563  }
564  break;
565 
566  case S_CURVE: // Bezier curve (TODO: not yet in use)
567  break;
568 
569  default:
570  break;
571  }
572 }
573 
574 
588  int aClearanceValue,
589  int aCircleToSegmentsCount,
590  double aCorrectionFactor ) const
591 {
592  switch( Type() )
593  {
594  case PCB_VIA_T:
595  {
596  int radius = (m_Width / 2) + aClearanceValue;
597  radius = KiROUND( radius * aCorrectionFactor );
598  TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aCircleToSegmentsCount );
599  }
600  break;
601 
602  default:
604  m_Start, m_End,
605  aCircleToSegmentsCount,
606  m_Width + ( 2 * aClearanceValue) );
607  break;
608  }
609 }
610 
611 
612 /* Function TransformShapeWithClearanceToPolygon
613  * Convert the pad shape to a closed polygon
614  * Used in filling zones calculations and 3D view generation
615  * Circles and arcs are approximated by segments
616  * aCornerBuffer = a SHAPE_POLY_SET to store the polygon corners
617  * aClearanceValue = the clearance around the pad
618  * aCircleToSegmentsCount = the number of segments to approximate a circle
619  * aCorrectionFactor = the correction to apply to circles radius to keep
620  * clearance when the circle is approximated by segment bigger or equal
621  * to the real clearance value (usually near from 1.0)
622  */
624  int aClearanceValue,
625  int aCircleToSegmentsCount,
626  double aCorrectionFactor ) const
627 {
628  double angle = m_Orient;
629  int dx = (m_Size.x / 2) + aClearanceValue;
630  int dy = (m_Size.y / 2) + aClearanceValue;
631 
632  wxPoint padShapePos = ShapePos(); /* Note: for pad having a shape offset,
633  * the pad position is NOT the shape position */
634 
635  switch( GetShape() )
636  {
637  case PAD_SHAPE_CIRCLE:
638  dx = KiROUND( dx * aCorrectionFactor );
639  TransformCircleToPolygon( aCornerBuffer, padShapePos, dx,
640  aCircleToSegmentsCount );
641  break;
642 
643  case PAD_SHAPE_OVAL:
644  // An oval pad has the same shape as a segment with rounded ends
645  {
646  int width;
647  wxPoint shape_offset;
648  if( dy > dx ) // Oval pad X/Y ratio for choosing translation axis
649  {
650  dy = KiROUND( dy * aCorrectionFactor );
651  shape_offset.y = dy - dx;
652  width = dx * 2;
653  }
654  else //if( dy <= dx )
655  {
656  dx = KiROUND( dx * aCorrectionFactor );
657  shape_offset.x = dy - dx;
658  width = dy * 2;
659  }
660 
661  RotatePoint( &shape_offset, angle );
662  wxPoint start = padShapePos - shape_offset;
663  wxPoint end = padShapePos + shape_offset;
664  TransformRoundedEndsSegmentToPolygon( aCornerBuffer, start, end,
665  aCircleToSegmentsCount, width );
666  }
667  break;
668 
669  case PAD_SHAPE_TRAPEZOID:
670  case PAD_SHAPE_RECT:
671  {
672  wxPoint corners[4];
673  BuildPadPolygon( corners, wxSize( 0, 0 ), angle );
674 
675  SHAPE_POLY_SET outline;
676  outline.NewOutline();
677 
678  for( int ii = 0; ii < 4; ii++ )
679  {
680  corners[ii] += padShapePos;
681  outline.Append( corners[ii].x, corners[ii].y );
682  }
683 
684  int rounding_radius = int( aClearanceValue * aCorrectionFactor );
685  outline.Inflate( rounding_radius, aCircleToSegmentsCount );
686 
687  aCornerBuffer.Append( outline );
688  }
689  break;
690 
691  case PAD_SHAPE_ROUNDRECT:
692  {
693  SHAPE_POLY_SET outline;
694  int pad_radius = GetRoundRectCornerRadius();
695  int clearance = int( aClearanceValue * aCorrectionFactor );
696  int rounding_radius = pad_radius + clearance;
697  wxSize shapesize( m_Size );
698  shapesize.x += clearance*2;
699  shapesize.y += clearance*2;
700 
701  TransformRoundRectToPolygon( outline, padShapePos, shapesize, angle,
702  rounding_radius, aCircleToSegmentsCount );
703 
704  aCornerBuffer.Append( outline );
705  }
706  break;
707  }
708 }
709 
710 
711 
712 
713 
714 /*
715  * Function BuildPadShapePolygon
716  * Build the Corner list of the polygonal shape,
717  * depending on shape, extra size (clearance ...) pad and orientation
718  * Note: for Round and oval pads this function is equivalent to
719  * TransformShapeWithClearanceToPolygon, but not for other shapes
720  */
722  wxSize aInflateValue, int aSegmentsPerCircle,
723  double aCorrectionFactor ) const
724 {
725  wxPoint corners[4];
726  wxPoint padShapePos = ShapePos(); /* Note: for pad having a shape offset,
727  * the pad position is NOT the shape position */
728  switch( GetShape() )
729  {
730  case PAD_SHAPE_CIRCLE:
731  case PAD_SHAPE_OVAL:
732  case PAD_SHAPE_ROUNDRECT:
733  TransformShapeWithClearanceToPolygon( aCornerBuffer, aInflateValue.x,
734  aSegmentsPerCircle, aCorrectionFactor );
735  break;
736 
737  case PAD_SHAPE_TRAPEZOID:
738  case PAD_SHAPE_RECT:
739  aCornerBuffer.NewOutline();
740 
741  BuildPadPolygon( corners, aInflateValue, m_Orient );
742  for( int ii = 0; ii < 4; ii++ )
743  {
744  corners[ii] += padShapePos; // Shift origin to position
745  aCornerBuffer.Append( corners[ii].x, corners[ii].y );
746  }
747 
748  break;
749  }
750 }
751 
752 /*
753  * Function BuildPadDrillShapePolygon
754  * Build the Corner list of the polygonal drill shape,
755  * depending on shape pad hole and orientation
756  * return false if the pad has no hole, true otherwise
757  */
759  int aInflateValue, int aSegmentsPerCircle ) const
760 {
761  wxSize drillsize = GetDrillSize();
762 
763  if( !drillsize.x || !drillsize.y )
764  return false;
765 
766  if( drillsize.x == drillsize.y ) // usual round hole
767  {
768  TransformCircleToPolygon( aCornerBuffer, GetPosition(),
769  (drillsize.x / 2) + aInflateValue, aSegmentsPerCircle );
770  }
771  else // Oblong hole
772  {
773  wxPoint start, end;
774  int width;
775 
776  GetOblongDrillGeometry( start, end, width );
777 
778  width += aInflateValue * 2;
779 
781  GetPosition() + start, GetPosition() + end, aSegmentsPerCircle, width );
782  }
783 
784  return true;
785 }
786 
801 /* thermal reliefs are created as 4 polygons.
802  * each corner of a polygon if calculated for a pad at position 0, 0, orient 0,
803  * and then moved and rotated acroding to the pad position and orientation
804  */
805 
806 /*
807  * Note 1: polygons are drawm using outlines witk a thickness = aMinThicknessValue
808  * so shapes must take in account this outline thickness
809  *
810  * Note 2:
811  * Trapezoidal pads are not considered here because they are very special case
812  * and are used in microwave applications and they *DO NOT* have a thermal relief that
813  * change the shape by creating stubs and destroy their properties.
814  */
816  D_PAD& aPad,
817  int aThermalGap,
818  int aCopperThickness,
819  int aMinThicknessValue,
820  int aCircleToSegmentsCount,
821  double aCorrectionFactor,
822  double aThermalRot )
823 {
824  wxPoint corner, corner_end;
825  wxPoint padShapePos = aPad.ShapePos(); // Note: for pad having a shape offset,
826  // the pad position is NOT the shape position
827  wxSize copper_thickness;
828 
829  double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
830 
831  /* Keep in account the polygon outline thickness
832  * aThermalGap must be increased by aMinThicknessValue/2 because drawing external outline
833  * with a thickness of aMinThicknessValue will reduce gap by aMinThicknessValue/2
834  */
835  aThermalGap += aMinThicknessValue / 2;
836 
837  /* Keep in account the polygon outline thickness
838  * copper_thickness must be decreased by aMinThicknessValue because drawing outlines
839  * with a thickness of aMinThicknessValue will increase real thickness by aMinThicknessValue
840  */
841  aCopperThickness -= aMinThicknessValue;
842 
843  if( aCopperThickness < 0 )
844  aCopperThickness = 0;
845 
846  int dx = aPad.GetSize().x / 2;
847  int dy = aPad.GetSize().y / 2;
848 
849  copper_thickness.x = std::min( dx, aCopperThickness );
850  copper_thickness.y = std::min( dy, aCopperThickness );
851 
852  switch( aPad.GetShape() )
853  {
854  case PAD_SHAPE_CIRCLE: // Add 4 similar holes
855  {
856  /* we create 4 copper holes and put them in position 1, 2, 3 and 4
857  * here is the area of the rectangular pad + its thermal gap
858  * the 4 copper holes remove the copper in order to create the thermal gap
859  * 4 ------ 1
860  * | |
861  * | |
862  * | |
863  * | |
864  * 3 ------ 2
865  * holes 2, 3, 4 are the same as hole 1, rotated 90, 180, 270 deg
866  */
867 
868  // Build the hole pattern, for the hole in the X >0, Y > 0 plane:
869  // The pattern roughtly is a 90 deg arc pie
870  std::vector <wxPoint> corners_buffer;
871 
872  // Radius of outer arcs of the shape corrected for arc approximation by lines
873  int outer_radius = KiROUND( (dx + aThermalGap) * aCorrectionFactor );
874 
875  // Crosspoint of thermal spoke sides, the first point of polygon buffer
876  corners_buffer.push_back( wxPoint( copper_thickness.x / 2, copper_thickness.y / 2 ) );
877 
878  // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side
879  // and first seg of arc approx
880  corner.x = copper_thickness.x / 2;
881  int y = outer_radius - (aThermalGap / 4);
882  corner.y = KiROUND( sqrt( ( (double) y * y - (double) corner.x * corner.x ) ) );
883 
884  if( aThermalRot != 0 )
885  corners_buffer.push_back( corner );
886 
887  // calculate the starting point of the outter arc
888  corner.x = copper_thickness.x / 2;
889 
890  corner.y = KiROUND( sqrt( ( (double) outer_radius * outer_radius ) -
891  ( (double) corner.x * corner.x ) ) );
892  RotatePoint( &corner, 90 ); // 9 degrees is the spoke fillet size
893 
894  // calculate the ending point of the outter arc
895  corner_end.x = corner.y;
896  corner_end.y = corner.x;
897 
898  // calculate intermediate points (y coordinate from corner.y to corner_end.y
899  while( (corner.y > corner_end.y) && (corner.x < corner_end.x) )
900  {
901  corners_buffer.push_back( corner );
902  RotatePoint( &corner, delta );
903  }
904 
905  corners_buffer.push_back( corner_end );
906 
907  /* add an intermediate point, to avoid angles < 90 deg between last arc approx line
908  * and radius line
909  */
910  corner.x = corners_buffer[1].y;
911  corner.y = corners_buffer[1].x;
912  corners_buffer.push_back( corner );
913 
914  // Now, add the 4 holes ( each is the pattern, rotated by 0, 90, 180 and 270 deg
915  // aThermalRot = 450 (45.0 degrees orientation) work fine.
916  double angle_pad = aPad.GetOrientation(); // Pad orientation
917  double th_angle = aThermalRot;
918 
919  for( unsigned ihole = 0; ihole < 4; ihole++ )
920  {
921  aCornerBuffer.NewOutline();
922 
923  for( unsigned ii = 0; ii < corners_buffer.size(); ii++ )
924  {
925  corner = corners_buffer[ii];
926  RotatePoint( &corner, th_angle + angle_pad ); // Rotate by segment angle and pad orientation
927  corner += padShapePos;
928  aCornerBuffer.Append( corner.x, corner.y );
929  }
930 
931  th_angle += 900; // Note: th_angle in in 0.1 deg.
932  }
933  }
934  break;
935 
936  case PAD_SHAPE_OVAL:
937  {
938  // Oval pad support along the lines of round and rectangular pads
939  std::vector <wxPoint> corners_buffer; // Polygon buffer as vector
940 
941  dx = (aPad.GetSize().x / 2) + aThermalGap; // Cutout radius x
942  dy = (aPad.GetSize().y / 2) + aThermalGap; // Cutout radius y
943 
944  wxPoint shape_offset;
945 
946  // We want to calculate an oval shape with dx > dy.
947  // if this is not the case, exchange dx and dy, and rotate the shape 90 deg.
948  int supp_angle = 0;
949 
950  if( dx < dy )
951  {
952  std::swap( dx, dy );
953  supp_angle = 900;
954  std::swap( copper_thickness.x, copper_thickness.y );
955  }
956 
957  int deltasize = dx - dy; // = distance between shape position and the 2 demi-circle ends centre
958  // here we have dx > dy
959  // Radius of outer arcs of the shape:
960  int outer_radius = dy; // The radius of the outer arc is radius end + aThermalGap
961 
962  // Some coordinate fiddling, depending on the shape offset direction
963  shape_offset = wxPoint( deltasize, 0 );
964 
965  // Crosspoint of thermal spoke sides, the first point of polygon buffer
966  corner.x = copper_thickness.x / 2;
967  corner.y = copper_thickness.y / 2;
968  corners_buffer.push_back( corner );
969 
970  // Arc start point calculation, the intersecting point of cutout arc and thermal spoke edge
971  // If copper thickness is more than shape offset, we need to calculate arc intercept point.
972  if( copper_thickness.x > deltasize )
973  {
974  corner.x = copper_thickness.x / 2;
975  corner.y = KiROUND( sqrt( ( (double) outer_radius * outer_radius ) -
976  ( (double) ( corner.x - delta ) * ( corner.x - deltasize ) ) ) );
977  corner.x -= deltasize;
978 
979  /* creates an intermediate point, to have a > 90 deg angle
980  * between the side and the first segment of arc approximation
981  */
982  wxPoint intpoint = corner;
983  intpoint.y -= aThermalGap / 4;
984  corners_buffer.push_back( intpoint + shape_offset );
985  RotatePoint( &corner, 90 ); // 9 degrees of thermal fillet
986  }
987  else
988  {
989  corner.x = copper_thickness.x / 2;
990  corner.y = outer_radius;
991  corners_buffer.push_back( corner );
992  }
993 
994  // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side
995  // and first seg of arc approx
996  wxPoint last_corner;
997  last_corner.y = copper_thickness.y / 2;
998  int px = outer_radius - (aThermalGap / 4);
999  last_corner.x =
1000  KiROUND( sqrt( ( ( (double) px * px ) - (double) last_corner.y * last_corner.y ) ) );
1001 
1002  // Arc stop point calculation, the intersecting point of cutout arc and thermal spoke edge
1003  corner_end.y = copper_thickness.y / 2;
1004  corner_end.x =
1005  KiROUND( sqrt( ( (double) outer_radius *
1006  outer_radius ) - ( (double) corner_end.y * corner_end.y ) ) );
1007  RotatePoint( &corner_end, -90 ); // 9 degrees of thermal fillet
1008 
1009  // calculate intermediate arc points till limit is reached
1010  while( (corner.y > corner_end.y) && (corner.x < corner_end.x) )
1011  {
1012  corners_buffer.push_back( corner + shape_offset );
1013  RotatePoint( &corner, delta );
1014  }
1015 
1016  //corners_buffer.push_back(corner + shape_offset); // TODO: about one mil geometry error forms somewhere.
1017  corners_buffer.push_back( corner_end + shape_offset );
1018  corners_buffer.push_back( last_corner + shape_offset ); // Enabling the line above shows intersection point.
1019 
1020  /* Create 2 holes, rotated by pad rotation.
1021  */
1022  double angle = aPad.GetOrientation() + supp_angle;
1023 
1024  for( int irect = 0; irect < 2; irect++ )
1025  {
1026  aCornerBuffer.NewOutline();
1027  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1028  {
1029  wxPoint cpos = corners_buffer[ic];
1030  RotatePoint( &cpos, angle );
1031  cpos += padShapePos;
1032  aCornerBuffer.Append( cpos.x, cpos.y );
1033  }
1034 
1035  angle = AddAngles( angle, 1800 ); // this is calculate hole 3
1036  }
1037 
1038  // Create holes, that are the mirrored from the previous holes
1039  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1040  {
1041  wxPoint swap = corners_buffer[ic];
1042  swap.x = -swap.x;
1043  corners_buffer[ic] = swap;
1044  }
1045 
1046  // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
1047  angle = aPad.GetOrientation() + supp_angle;
1048 
1049  for( int irect = 0; irect < 2; irect++ )
1050  {
1051  aCornerBuffer.NewOutline();
1052 
1053  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1054  {
1055  wxPoint cpos = corners_buffer[ic];
1056  RotatePoint( &cpos, angle );
1057  cpos += padShapePos;
1058  aCornerBuffer.Append( cpos.x, cpos.y );
1059  }
1060 
1061  angle = AddAngles( angle, 1800 );
1062  }
1063  }
1064  break;
1065 
1066  case PAD_SHAPE_ROUNDRECT: // thermal shape is the same for round rect and rect.
1067  case PAD_SHAPE_RECT:
1068  {
1069  /* we create 4 copper holes and put them in position 1, 2, 3 and 4
1070  * here is the area of the rectangular pad + its thermal gap
1071  * the 4 copper holes remove the copper in order to create the thermal gap
1072  * 4 ------ 1
1073  * | |
1074  * | |
1075  * | |
1076  * | |
1077  * 3 ------ 2
1078  * hole 3 is the same as hole 1, rotated 180 deg
1079  * hole 4 is the same as hole 2, rotated 180 deg and is the same as hole 1, mirrored
1080  */
1081 
1082  // First, create a rectangular hole for position 1 :
1083  // 2 ------- 3
1084  // | |
1085  // | |
1086  // | |
1087  // 1 -------4
1088 
1089  // Modified rectangles with one corner rounded. TODO: merging with oval thermals
1090  // and possibly round too.
1091 
1092  std::vector <wxPoint> corners_buffer; // Polygon buffer as vector
1093 
1094  dx = (aPad.GetSize().x / 2) + aThermalGap; // Cutout radius x
1095  dy = (aPad.GetSize().y / 2) + aThermalGap; // Cutout radius y
1096 
1097  // The first point of polygon buffer is left lower corner, second the crosspoint of
1098  // thermal spoke sides, the third is upper right corner and the rest are rounding
1099  // vertices going anticlockwise. Note the inveted Y-axis in CG.
1100  corners_buffer.push_back( wxPoint( -dx, -(aThermalGap / 4 + copper_thickness.y / 2) ) ); // Adds small miters to zone
1101  corners_buffer.push_back( wxPoint( -(dx - aThermalGap / 4), -copper_thickness.y / 2 ) ); // fill and spoke corner
1102  corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -copper_thickness.y / 2 ) );
1103  corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -(dy - aThermalGap / 4) ) );
1104  corners_buffer.push_back( wxPoint( -(aThermalGap / 4 + copper_thickness.x / 2), -dy ) );
1105 
1106  double angle = aPad.GetOrientation();
1107  int rounding_radius = KiROUND( aThermalGap * aCorrectionFactor ); // Corner rounding radius
1108 
1109  for( int i = 0; i < aCircleToSegmentsCount / 4 + 1; i++ )
1110  {
1111  wxPoint corner_position = wxPoint( 0, -rounding_radius );
1112 
1113  // Start at half increment offset
1114  RotatePoint( &corner_position, 1800.0 / aCircleToSegmentsCount );
1115  double angle_pg = i * delta;
1116 
1117  RotatePoint( &corner_position, angle_pg ); // Rounding vector rotation
1118  corner_position -= aPad.GetSize() / 2; // Rounding vector + Pad corner offset
1119 
1120  corners_buffer.push_back( wxPoint( corner_position.x, corner_position.y ) );
1121  }
1122 
1123  for( int irect = 0; irect < 2; irect++ )
1124  {
1125  aCornerBuffer.NewOutline();
1126 
1127  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1128  {
1129  wxPoint cpos = corners_buffer[ic];
1130  RotatePoint( &cpos, angle ); // Rotate according to module orientation
1131  cpos += padShapePos; // Shift origin to position
1132  aCornerBuffer.Append( cpos.x, cpos.y );
1133  }
1134 
1135  angle = AddAngles( angle, 1800 ); // this is calculate hole 3
1136  }
1137 
1138  // Create holes, that are the mirrored from the previous holes
1139  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1140  {
1141  wxPoint swap = corners_buffer[ic];
1142  swap.x = -swap.x;
1143  corners_buffer[ic] = swap;
1144  }
1145 
1146  // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
1147  for( int irect = 0; irect < 2; irect++ )
1148  {
1149  aCornerBuffer.NewOutline();
1150 
1151  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1152  {
1153  wxPoint cpos = corners_buffer[ic];
1154  RotatePoint( &cpos, angle );
1155  cpos += padShapePos;
1156  aCornerBuffer.Append( cpos.x, cpos.y );
1157  }
1158 
1159  angle = AddAngles( angle, 1800 );
1160  }
1161  }
1162  break;
1163 
1164  case PAD_SHAPE_TRAPEZOID:
1165  {
1166  SHAPE_POLY_SET antipad; // The full antipad area
1167 
1168  // We need a length to build the stubs of the thermal reliefs
1169  // the value is not very important. The pad bounding box gives a reasonable value
1170  EDA_RECT bbox = aPad.GetBoundingBox();
1171  int stub_len = std::max( bbox.GetWidth(), bbox.GetHeight() );
1172 
1173  aPad.TransformShapeWithClearanceToPolygon( antipad, aThermalGap,
1174  aCircleToSegmentsCount, aCorrectionFactor );
1175 
1176  SHAPE_POLY_SET stub; // A basic stub ( a rectangle)
1177  SHAPE_POLY_SET stubs; // the full stubs shape
1178 
1179 
1180  // We now substract the stubs (connections to the copper zone)
1181  //ClipperLib::Clipper clip_engine;
1182  // Prepare a clipping transform
1183  //clip_engine.AddPath( antipad, ClipperLib::ptSubject, true );
1184 
1185  // Create stubs and add them to clipper engine
1186  wxPoint stubBuffer[4];
1187  stubBuffer[0].x = stub_len;
1188  stubBuffer[0].y = copper_thickness.y/2;
1189  stubBuffer[1] = stubBuffer[0];
1190  stubBuffer[1].y = -copper_thickness.y/2;
1191  stubBuffer[2] = stubBuffer[1];
1192  stubBuffer[2].x = -stub_len;
1193  stubBuffer[3] = stubBuffer[2];
1194  stubBuffer[3].y = copper_thickness.y/2;
1195 
1196  stub.NewOutline();
1197 
1198  for( unsigned ii = 0; ii < DIM( stubBuffer ); ii++ )
1199  {
1200  wxPoint cpos = stubBuffer[ii];
1201  RotatePoint( &cpos, aPad.GetOrientation() );
1202  cpos += padShapePos;
1203  stub.Append( cpos.x, cpos.y );
1204  }
1205 
1206  stubs.Append( stub );
1207 
1208  stubBuffer[0].y = stub_len;
1209  stubBuffer[0].x = copper_thickness.x/2;
1210  stubBuffer[1] = stubBuffer[0];
1211  stubBuffer[1].x = -copper_thickness.x/2;
1212  stubBuffer[2] = stubBuffer[1];
1213  stubBuffer[2].y = -stub_len;
1214  stubBuffer[3] = stubBuffer[2];
1215  stubBuffer[3].x = copper_thickness.x/2;
1216 
1217  stub.RemoveAllContours();
1218  stub.NewOutline();
1219 
1220  for( unsigned ii = 0; ii < DIM( stubBuffer ); ii++ )
1221  {
1222  wxPoint cpos = stubBuffer[ii];
1223  RotatePoint( &cpos, aPad.GetOrientation() );
1224  cpos += padShapePos;
1225  stub.Append( cpos.x, cpos.y );
1226  }
1227 
1228  stubs.Append( stub );
1230 
1231  antipad.BooleanSubtract( stubs, SHAPE_POLY_SET::PM_FAST );
1232  aCornerBuffer.Append( antipad );
1233 
1234  break;
1235  }
1236 
1237  default:
1238  ;
1239  }
1240 }
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:198
#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:78
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)
Definition: drawtxt.cpp:122
TEXTE_MODULE & Reference()
Definition: class_module.h:455
wxPoint m_Start
Line start point.
Definition: class_track.h:339
static SHAPE_POLY_SET * s_cornerBuffer
bool IsMultilineAllowed() const
Definition: eda_text.h:188
double GetDrawRotation() const
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:238
TEXTE_PCB class definition.
const wxPoint & GetTextPos() const
Definition: eda_text.h:224
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:170
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:63
int GetMinThickness() const
Definition: class_zone.h:209
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
const wxPoint GetCenter() const override
Function GetCenter()
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
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()
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 GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:351
polygon (not yet used for tracks, but could be in microwave apps)
MODULE * Next() const
Definition: class_module.h:99
wxSize m_Size
X and Y size ( relative to orient 0)
Definition: class_pad.h:620
int GetHeight() const
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
Classes to handle copper zones.
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:221
usual segment : line with rounded ends
const std::vector< wxPoint > & GetPolyPoints() const
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
double m_Angle
Used only for Arcs: Arc angle in 1/10 deg.
int OutlineCount() const
Returns the number of outlines in the set
const wxSize & GetDrillSize() const
Definition: class_pad.h:188
virtual wxString GetShownText() const override
Returns the string actually shown after processing of the base text.
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:166
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:190
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
DLIST< BOARD_ITEM > & GraphicalItems()
Definition: class_module.h:136
static const int delta[8][2]
Definition: solve.cpp:112
double GetTextAngle() const
Definition: eda_text.h:164
Functions relatives to tracks, vias and segments used to fill zones.
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:154
int m_Width
Thickness of track, or via diameter.
Definition: class_track.h:338
void TransformSolidAreasShapesToPolygonSet(SHAPE_POLY_SET &aCornerBuffer, int aCircleToSegmentsCount, double aCorrectionFactor) const
Function TransformSolidAreasShapesToPolygonSet Convert solid areas full shapes to polygon set (the fu...
const wxPoint & GetArcStart() const
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:135
BOARD_ITEM * Next() const
const wxPoint & GetOrigin() const
PCB_LAYER_ID
A quick note on layer IDs:
wxPoint m_Start
Line start point or Circle and Arc center.
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const
Function TransformShapeWithClearanceToPolygon Convert the pad shape to a closed polygon Used in filli...
EDA_RECT GetTextBox(int aLine=-1, int aThickness=-1, bool aInvertY=false) const
Function GetTextBox useful in multiline texts to calculate the full text or a line area (for zones fi...
Definition: eda_text.cpp:115
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...
wxPoint m_End
Line end point or circle and arc start point.
T AddAngles(T a1, T2 a2)
Add two angles (keeping the result normalized). T2 is here.
Definition: trigo.h:246
double GetOrientation() const
Definition: class_module.h:147
Class SHAPE_POLY_SET.
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:454
int GetSolderMaskMargin() const
Function GetSolderMaskMargin.
Definition: class_pad.cpp:537
const wxPoint & GetPosition() const override
Definition: class_pad.h:170
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:130
Arcs (with rounded ends)
wxPoint m_End
Line end point.
Definition: class_track.h:340
D_PAD * Next() const
Definition: class_pad.h:106
const wxSize & GetSize() const
Definition: class_pad.h:182
DLIST< BOARD_ITEM > m_Drawings
Definition: class_board.h:242
void ConvertBrdLayerToPolygonalContours(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aOutlines)
Function ConvertBrdLayerToPolygonalContours Build a set of polygons which are the outlines of copper ...
void GetPositionsOfLinesOfMultilineText(std::vector< wxPoint > &aPositions, int aLineCount) const
Function GetPositionsOfLinesOfMultilineText Populates aPositions with the position of each line of a ...
Definition: eda_text.cpp:327
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
STROKE_T m_Shape
Shape: line, Circle, Arc.
void Simplify(POLYGON_MODE aFastMode)
Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFast...
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:1051
int GetBottom() const
Bezier Curve.
int GetRight() const
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...
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const
Function TransformShapeWithClearanceToPolygon Convert the track shape to a closed polygon Used in fil...
int NewOutline()
Creates a new empty polygon in the set and returns its index
SHAPE_POLY_SET m_FilledPolysList
Definition: class_zone.h:788
const SHAPE_POLY_SET & GetFilledPolysList() const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: class_zone.h:587
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor) const
Function TransformShapeWithClearanceToPolygon Convert the track shape to a closed polygon Used in fil...
Pad object description.
void TransformGraphicShapesWithClearanceToPolygonSet(PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, int aCircleToSegmentsCount, double aCorrectionFactor, int aCircleToSegmentsCountForTexts=0) const
function TransformGraphicShapesWithClearanceToPolygonSet generate shapes of graphic items (outlines) ...
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:105
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:191
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...
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void CreateThermalReliefPadPolygon(SHAPE_POLY_SET &aCornerBuffer, 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...
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:98
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:1022
Class to handle a graphic segment.
void GetOblongDrillGeometry(wxPoint &aStartPoint, wxPoint &aEndPoint, int &aWidth) const
Function GetOblongDrillGeometry calculates the start point, end point and width of an equivalent segm...
Definition: class_pad.cpp:718
#define max(a, b)
Definition: auxiliary.h:86
bool IsMirrored() const
Definition: eda_text.h:179
DLIST< MODULE > m_Modules
Definition: class_board.h:243
Class SHAPE_LINE_CHAIN.
bool IsVisible() const
Definition: eda_text.h:176
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:214
Class EDA_RECT handles the component boundary box.
wxSize GetSolderPasteMargin() const
Function GetSolderPasteMargin.
Definition: class_pad.cpp:570
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
int GetWidth() const
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:418
MODULE * GetParentModule() const
Function GetParentModule returns a pointer to the parent module, or NULL if DRAWSEGMENT does not belo...
This file is part of the common libary.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
static int s_textCircle2SegmentCount
DLIST< D_PAD > & Pads()
Definition: class_module.h:133
DLIST< TRACK > m_Track
Definition: class_board.h:244
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset difference For aFastMode meaning, see function booleanOp ...
int m_Width
thickness of lines ...
Module description (excepted pads)
Definition: colors.h:45
const wxSize & GetTextSize() const
Definition: eda_text.h:215
double m_Orient
in 1/10 degrees
Definition: class_pad.h:654
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:479
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:103
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
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 EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: class_pad.cpp:181
const wxPoint & GetOffset() const
Definition: class_pad.h:191
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
const wxPoint & GetPosition() const override
#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