KiCad PCB EDA Suite
create_layer_poly.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) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
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 
33 #include "cinfo3d_visu.h"
35 #include <class_edge_mod.h>
36 #include <class_module.h>
37 
38 
39 // This is the same function as in board_items_to_polygon_shape_transform.cpp
40 // but it adds the rect/trapezoid shapes with a different winding
42  SHAPE_POLY_SET& aCornerBuffer,
43  wxSize aInflateValue,
44  int aSegmentsPerCircle,
45  double aCorrectionFactor ) const
46 {
47  wxPoint corners[4];
48  wxPoint PadShapePos = aPad->ShapePos(); /* Note: for pad having a shape offset,
49  * the pad position is NOT the shape position */
50  switch( aPad->GetShape() )
51  {
52  case PAD_SHAPE_CIRCLE:
53  case PAD_SHAPE_OVAL:
55  {
56  // We are using TransformShapeWithClearanceToPolygon to build the shape.
57  // Currently, this method uses only the same inflate value for X and Y dirs.
58  // so because here this is not the case, we use a inflated dummy pad to build
59  // the polygonal shape
60  // TODO: remove this dummy pad when TransformShapeWithClearanceToPolygon will use
61  // a wxSize to inflate the pad size
62  D_PAD dummy( *aPad );
63  wxSize new_size = aPad->GetSize() + aInflateValue + aInflateValue;
64  dummy.SetSize( new_size );
65  dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, 0,
66  aSegmentsPerCircle, aCorrectionFactor );
67  }
68  break;
69 
71  case PAD_SHAPE_RECT:
72  {
73  SHAPE_LINE_CHAIN aLineChain;
74 
75  aPad->BuildPadPolygon( corners, aInflateValue, aPad->GetOrientation() );
76 
77  for( int ii = 0; ii < 4; ++ii )
78  {
79  corners[3-ii] += PadShapePos; // Shift origin to position
80  aLineChain.Append( corners[3-ii].x, corners[3-ii].y );
81  }
82 
83  aLineChain.SetClosed( true );
84 
85  aCornerBuffer.AddOutline( aLineChain );
86  }
87  break;
88 
89  case PAD_SHAPE_CUSTOM:
90  {
91  SHAPE_POLY_SET polyList; // Will contain the pad outlines in board coordinates
92  polyList.Append( aPad->GetCustomShapeAsPolygon() );
93  aPad->CustomShapeAsPolygonToBoardPosition( &polyList, aPad->ShapePos(), aPad->GetOrientation() );
94  aCornerBuffer.Append( polyList );
95  }
96  break;
97  }
98 }
99 
100 
102  SHAPE_POLY_SET& aCornerBuffer,
103  int aWidth ) const
104 {
105  if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // Draw a ring
106  {
107  unsigned int nr_sides_per_circle = GetNrSegmentsCircle( ( aPad->GetSize().x / 2 +
108  aWidth / 2 ) * 2 );
109 
110  TransformRingToPolygon( aCornerBuffer, aPad->ShapePos(),
111  aPad->GetSize().x / 2, nr_sides_per_circle, aWidth );
112  return;
113  }
114 
115 
116  // For other shapes, draw polygon outlines
117  SHAPE_POLY_SET corners;
118 
119  unsigned int nr_sides_per_circle = GetNrSegmentsCircle( glm::min( aPad->GetSize().x,
120  aPad->GetSize().y) );
121  buildPadShapePolygon( aPad, corners, wxSize( 0, 0 ),
122  nr_sides_per_circle,
123  GetCircleCorrectionFactor( nr_sides_per_circle ) );
124 
125  // Add outlines as thick segments in polygon buffer
126 
127  const SHAPE_LINE_CHAIN& path = corners.COutline( 0 );
128 
129  for( int ii = 0; ii < path.PointCount(); ++ii )
130  {
131  const VECTOR2I& a = path.CPoint( ii );
132  const VECTOR2I& b = path.CPoint( ii + 1 );
133 
135  wxPoint( a.x, a.y ),
136  wxPoint( b.x, b.y ),
137  nr_sides_per_circle,
138  aWidth );
139  }
140 }
141 
142 
143 // Based on the same function name in board_items_to_polyshape_transform.cpp
144 // It was implemented here to allow dynamic segments count per pad shape
146  SHAPE_POLY_SET& aCornerBuffer,
147  int aInflateValue,
148  bool aSkipNPTHPadsWihNoCopper ) const
149 {
150  const D_PAD* pad = aPads;
151 
152  wxSize margin;
153  for( ; pad != NULL; pad = pad->Next() )
154  {
155  if( !pad->IsOnLayer(aLayer) )
156  continue;
157 
158  // NPTH pads are not drawn on layers if the shape size and pos is the same
159  // as their hole:
160  if( aSkipNPTHPadsWihNoCopper && (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED) )
161  {
162  if( (pad->GetDrillSize() == pad->GetSize()) &&
163  (pad->GetOffset() == wxPoint( 0, 0 )) )
164  {
165  switch( pad->GetShape() )
166  {
167  case PAD_SHAPE_CIRCLE:
168  if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
169  continue;
170  break;
171 
172  case PAD_SHAPE_OVAL:
173  if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
174  continue;
175  break;
176 
177  default:
178  break;
179  }
180  }
181  }
182 
183  switch( aLayer )
184  {
185  case F_Mask:
186  case B_Mask:
187  margin.x = margin.y = pad->GetSolderMaskMargin() + aInflateValue;
188  break;
189 
190  case F_Paste:
191  case B_Paste:
192  margin = pad->GetSolderPasteMargin();
193  margin.x += aInflateValue;
194  margin.y += aInflateValue;
195  break;
196 
197  default:
198  margin.x = margin.y = aInflateValue;
199  break;
200  }
201 
202  unsigned int aCircleToSegmentsCount = GetNrSegmentsCircle( pad->GetSize().x );
203  double aCorrectionFactor = GetCircleCorrectionFactor( aCircleToSegmentsCount );
204 
205  buildPadShapePolygon( pad, aCornerBuffer, margin,
206  aCircleToSegmentsCount, aCorrectionFactor );
207  }
208 }
209 
211  PCB_LAYER_ID aLayer,
212  SHAPE_POLY_SET& aCornerBuffer ) const
213 {
214  for( const EDA_ITEM* item = aModule->GraphicalItemsList();
215  item != NULL;
216  item = item->Next() )
217  {
218  switch( item->Type() )
219  {
220  case PCB_MODULE_EDGE_T:
221  {
222  EDGE_MODULE*outline = (EDGE_MODULE*) item;
223 
224  if( outline->GetLayer() != aLayer )
225  break;
226 
227  unsigned int aCircleToSegmentsCount =
229 
230  double aCorrectionFactor = GetCircleCorrectionFactor( aCircleToSegmentsCount );
231 
232  outline->TransformShapeWithClearanceToPolygon( aCornerBuffer,
233  0,
234  aCircleToSegmentsCount,
235  aCorrectionFactor );
236  }
237  break;
238 
239  default:
240  break;
241  }
242  }
243 }
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...
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:405
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:65
const SHAPE_POLY_SET & GetCustomShapeAsPolygon() const
Accessor to the custom shape as one polygon.
Definition: class_pad.h:341
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int PointCount() const
Function PointCount()
Handles data related with the board to be visualized.
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:388
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
BOARD_ITEM * Next() const
void SetClosed(bool aClosed)
Function SetClosed()
PCB_LAYER_ID
A quick note on layer IDs:
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0...
Class SHAPE_POLY_SET.
int GetSolderMaskMargin() const
Function GetSolderMaskMargin.
Definition: class_pad.cpp:585
int GetSizeMax() const
GetSizeMax.
Definition: eda_rect.h:107
D_PAD * Next() const
Definition: class_pad.h:160
const wxSize & GetSize() const
Definition: class_pad.h:269
void SetSize(const wxSize &aSize)
Definition: class_pad.h:268
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
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...
unsigned int GetNrSegmentsCircle(float aDiameter3DU) const
GetNrSegmentsCircle.
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...
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index
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 transformPadsShapesWithClearanceToPolygon(const DLIST< D_PAD > &aPads, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, bool aSkipNPTHPadsWihNoCopper) const
double GetCircleCorrectionFactor(int aNrSides) const
GetCircleCorrectionFactor - computes a angle correction factor used when creating circles...
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
Class SHAPE_LINE_CHAIN.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:382
wxSize GetSolderPasteMargin() const
Function GetSolderPasteMargin.
Definition: class_pad.cpp:628
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
wxPoint ShapePos() const
Definition: class_pad.cpp:508
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:166
Module description (excepted pads)
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:654
EDGE_MODULE class definition.
void buildPadShapePolygon(const D_PAD *aPad, SHAPE_POLY_SET &aCornerBuffer, wxSize aInflateValue, int aSegmentsPerCircle, double aCorrectionFactor) const
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
const wxPoint & GetOffset() const
Definition: class_pad.h:278
void transformGraphicModuleEdgeToPolygonSet(const MODULE *aModule, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer) const
void buildPadShapeThickOutlineAsPolygon(const D_PAD *aPad, SHAPE_POLY_SET &aCornerBuffer, int aWidth) const
#define min(a, b)
Definition: auxiliary.h:85
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) ...
virtual const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...