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  aPad->TransformShapeWithClearanceToPolygon( aCornerBuffer, aInflateValue.x,
56  aSegmentsPerCircle, aCorrectionFactor );
57  break;
58 
60  case PAD_SHAPE_RECT:
61  {
62  SHAPE_LINE_CHAIN aLineChain;
63 
64  aPad->BuildPadPolygon( corners, aInflateValue, aPad->GetOrientation() );
65 
66  for( int ii = 0; ii < 4; ++ii )
67  {
68  corners[3-ii] += PadShapePos; // Shift origin to position
69  aLineChain.Append( corners[3-ii].x, corners[3-ii].y );
70  }
71 
72  aLineChain.SetClosed( true );
73 
74  aCornerBuffer.AddOutline( aLineChain );
75  }
76  break;
77 
78  case PAD_SHAPE_CUSTOM:
79  {
80  SHAPE_POLY_SET polyList; // Will contain the pad outlines in board coordinates
81  polyList.Append( aPad->GetCustomShapeAsPolygon() );
82  aPad->CustomShapeAsPolygonToBoardPosition( &polyList, aPad->ShapePos(), aPad->GetOrientation() );
83  aCornerBuffer.Append( polyList );
84  }
85  break;
86  }
87 }
88 
89 
91  SHAPE_POLY_SET& aCornerBuffer,
92  int aWidth ) const
93 {
94  if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // Draw a ring
95  {
96  unsigned int nr_sides_per_circle = GetNrSegmentsCircle( ( aPad->GetSize().x / 2 +
97  aWidth / 2 ) * 2 );
98 
99  TransformRingToPolygon( aCornerBuffer, aPad->ShapePos(),
100  aPad->GetSize().x / 2, nr_sides_per_circle, aWidth );
101  return;
102  }
103 
104 
105  // For other shapes, draw polygon outlines
106  SHAPE_POLY_SET corners;
107 
108  unsigned int nr_sides_per_circle = GetNrSegmentsCircle( glm::min( aPad->GetSize().x,
109  aPad->GetSize().y) );
110  buildPadShapePolygon( aPad, corners, wxSize( 0, 0 ),
111  nr_sides_per_circle,
112  GetCircleCorrectionFactor( nr_sides_per_circle ) );
113 
114  // Add outlines as thick segments in polygon buffer
115 
116  const SHAPE_LINE_CHAIN& path = corners.COutline( 0 );
117 
118  for( int ii = 0; ii < path.PointCount(); ++ii )
119  {
120  const VECTOR2I& a = path.CPoint( ii );
121  const VECTOR2I& b = path.CPoint( ii + 1 );
122 
124  wxPoint( a.x, a.y ),
125  wxPoint( b.x, b.y ),
126  nr_sides_per_circle,
127  aWidth );
128  }
129 }
130 
131 
132 // Based on the same function name in board_items_to_polyshape_transform.cpp
133 // It was implemented here to allow dynamic segments count per pad shape
135  SHAPE_POLY_SET& aCornerBuffer,
136  int aInflateValue,
137  bool aSkipNPTHPadsWihNoCopper ) const
138 {
139  const D_PAD* pad = aPads;
140 
141  wxSize margin;
142  for( ; pad != NULL; pad = pad->Next() )
143  {
144  if( !pad->IsOnLayer(aLayer) )
145  continue;
146 
147  // NPTH pads are not drawn on layers if the shape size and pos is the same
148  // as their hole:
149  if( aSkipNPTHPadsWihNoCopper && (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED) )
150  {
151  if( (pad->GetDrillSize() == pad->GetSize()) &&
152  (pad->GetOffset() == wxPoint( 0, 0 )) )
153  {
154  switch( pad->GetShape() )
155  {
156  case PAD_SHAPE_CIRCLE:
157  if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
158  continue;
159  break;
160 
161  case PAD_SHAPE_OVAL:
162  if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
163  continue;
164  break;
165 
166  default:
167  break;
168  }
169  }
170  }
171 
172  switch( aLayer )
173  {
174  case F_Mask:
175  case B_Mask:
176  margin.x = margin.y = pad->GetSolderMaskMargin() + aInflateValue;
177  break;
178 
179  case F_Paste:
180  case B_Paste:
181  margin = pad->GetSolderPasteMargin();
182  margin.x += aInflateValue;
183  margin.y += aInflateValue;
184  break;
185 
186  default:
187  margin.x = margin.y = aInflateValue;
188  break;
189  }
190 
191  unsigned int aCircleToSegmentsCount = GetNrSegmentsCircle( pad->GetSize().x );
192  double aCorrectionFactor = GetCircleCorrectionFactor( aCircleToSegmentsCount );
193 
194  buildPadShapePolygon( pad, aCornerBuffer, margin,
195  aCircleToSegmentsCount, aCorrectionFactor );
196  }
197 }
198 
200  PCB_LAYER_ID aLayer,
201  SHAPE_POLY_SET& aCornerBuffer ) const
202 {
203  for( const EDA_ITEM* item = aModule->GraphicalItemsList();
204  item != NULL;
205  item = item->Next() )
206  {
207  switch( item->Type() )
208  {
209  case PCB_MODULE_EDGE_T:
210  {
211  EDGE_MODULE*outline = (EDGE_MODULE*) item;
212 
213  if( outline->GetLayer() != aLayer )
214  break;
215 
216  unsigned int aCircleToSegmentsCount =
218 
219  double aCorrectionFactor = GetCircleCorrectionFactor( aCircleToSegmentsCount );
220 
221  outline->TransformShapeWithClearanceToPolygon( aCornerBuffer,
222  0,
223  aCircleToSegmentsCount,
224  aCorrectionFactor );
225  }
226  break;
227 
228  default:
229  break;
230  }
231  }
232 }
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:398
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:381
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:106
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 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...
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:577
int GetSizeMax() const
GetSizeMax.
D_PAD * Next() const
Definition: class_pad.h:160
const wxSize & GetSize() const
Definition: class_pad.h:269
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
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...
unsigned int GetNrSegmentsCircle(float aDiameter3DU) const
GetNrSegmentsCircle.
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...
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:375
wxSize GetSolderPasteMargin() const
Function GetSolderPasteMargin.
Definition: class_pad.cpp:610
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:165
wxPoint ShapePos() const
Definition: class_pad.cpp:500
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:137
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:637
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...