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-2019 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 ) const
44 {
45  wxPoint corners[4];
46  wxPoint PadShapePos = aPad->ShapePos(); /* Note: for pad having a shape offset,
47  * the pad position is NOT the shape position */
48  switch( aPad->GetShape() )
49  {
50  case PAD_SHAPE_CIRCLE:
51  case PAD_SHAPE_OVAL:
54  {
55  // We are using TransformShapeWithClearanceToPolygon to build the shape.
56  // Currently, this method uses only the same inflate value for X and Y dirs.
57  // so because here this is not the case, we use a inflated dummy pad to build
58  // the polygonal shape
59  // TODO: remove this dummy pad when TransformShapeWithClearanceToPolygon will use
60  // a wxSize to inflate the pad size
61  D_PAD dummy( *aPad );
62  wxSize new_size = aPad->GetSize() + aInflateValue + aInflateValue;
63  dummy.SetSize( new_size );
64  dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, 0 );
65  }
66  break;
67 
69  case PAD_SHAPE_RECT:
70  {
71  SHAPE_LINE_CHAIN aLineChain;
72 
73  aPad->BuildPadPolygon( corners, aInflateValue, aPad->GetOrientation() );
74 
75  for( int ii = 0; ii < 4; ++ii )
76  {
77  corners[3-ii] += PadShapePos; // Shift origin to position
78  aLineChain.Append( corners[3-ii].x, corners[3-ii].y );
79  }
80 
81  aLineChain.SetClosed( true );
82 
83  aCornerBuffer.AddOutline( aLineChain );
84  }
85  break;
86 
87  case PAD_SHAPE_CUSTOM:
88  {
89  SHAPE_POLY_SET polyList; // Will contain the pad outlines in board coordinates
90  auto inflate_val = std::max( aInflateValue.x, aInflateValue.y );
91 
92  polyList.Append( aPad->GetCustomShapeAsPolygon() );
93  aPad->CustomShapeAsPolygonToBoardPosition( &polyList, aPad->ShapePos(), aPad->GetOrientation() );
94 
95  if( inflate_val > 0 )
96  {
97  int numSegs = GetNrSegmentsCircle( inflate_val );
98  polyList.Inflate( inflate_val, numSegs );
99  }
100 
101  aCornerBuffer.Append( polyList );
102  }
103  break;
104  }
105 }
106 
107 
109  SHAPE_POLY_SET& aCornerBuffer,
110  int aWidth ) const
111 {
112  if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // Draw a ring
113  {
114  TransformRingToPolygon( aCornerBuffer, aPad->ShapePos(),
115  aPad->GetSize().x / 2, ARC_HIGH_DEF, aWidth );
116  return;
117  }
118 
119 
120  // For other shapes, draw polygon outlines
121  SHAPE_POLY_SET corners;
122 
123  buildPadShapePolygon( aPad, corners, wxSize( 0, 0 ) );
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 
134  TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ),
135  wxPoint( b.x, b.y ), ARC_HIGH_DEF, aWidth );
136  }
137 }
138 
139 
140 // Based on the same function name in board_items_to_polyshape_transform.cpp
141 // It was implemented here to allow dynamic segments count per pad shape
143  SHAPE_POLY_SET& aCornerBuffer,
144  int aInflateValue,
145  bool aSkipNPTHPadsWihNoCopper ) const
146 {
147  wxSize margin;
148  for( auto pad : aPads )
149  {
150  if( !pad->IsOnLayer(aLayer) )
151  continue;
152 
153  // NPTH pads are not drawn on layers if the shape size and pos is the same
154  // as their hole:
155  if( aSkipNPTHPadsWihNoCopper && (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED) )
156  {
157  if( (pad->GetDrillSize() == pad->GetSize()) &&
158  (pad->GetOffset() == wxPoint( 0, 0 )) )
159  {
160  switch( pad->GetShape() )
161  {
162  case PAD_SHAPE_CIRCLE:
163  if( pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
164  continue;
165  break;
166 
167  case PAD_SHAPE_OVAL:
168  if( pad->GetDrillShape() != PAD_DRILL_SHAPE_CIRCLE )
169  continue;
170  break;
171 
172  default:
173  break;
174  }
175  }
176  }
177 
178  switch( aLayer )
179  {
180  case F_Mask:
181  case B_Mask:
182  margin.x = margin.y = pad->GetSolderMaskMargin() + aInflateValue;
183  break;
184 
185  case F_Paste:
186  case B_Paste:
187  margin = pad->GetSolderPasteMargin();
188  margin.x += aInflateValue;
189  margin.y += aInflateValue;
190  break;
191 
192  default:
193  margin.x = margin.y = aInflateValue;
194  break;
195  }
196 
197  buildPadShapePolygon( pad, aCornerBuffer, margin );
198  }
199 }
200 
202  PCB_LAYER_ID aLayer,
203  SHAPE_POLY_SET& aCornerBuffer ) const
204 {
205  for( auto item : aModule->GraphicalItems() )
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  outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, 0 );
217  }
218  break;
219 
220  default:
221  break;
222  }
223  }
224 }
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:66
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aError=ARC_HIGH_DEF, bool ignoreLineWidth=false) const override
Function TransformShapeWithClearanceToPolygon Convert the draw segment to a closed polygon Used in fi...
unsigned int GetNrSegmentsCircle(float aDiameter3DU) const
GetNrSegmentsCircle.
Handles data related with the board to be visualized.
void TransformRingToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCentre, int aRadius, int aError, int aWidth)
Function TransformRingToPolygon Creates a polygon from a ring Convert arcs to multiple straight segme...
DRAWINGS & GraphicalItems()
Definition: class_module.h:173
void Inflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Performs outline inflation/deflation.
int PointCount() const
Function PointCount()
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
void SetClosed(bool aClosed)
Function SetClosed()
PCB_LAYER_ID
A quick note on layer IDs:
void TransformRoundedEndsSegmentToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aError, int aWidth)
Function TransformRoundedEndsSegmentToPolygon convert a segment with rounded ends to a polygon Conver...
Class SHAPE_POLY_SET.
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
#define max(a, b)
Definition: auxiliary.h:86
Class SHAPE_LINE_CHAIN.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:406
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0,...
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
wxPoint ShapePos() const
Definition: class_pad.cpp:570
const SHAPE_POLY_SET & GetCustomShapeAsPolygon() const
Accessor to the custom shape as one polygon.
Definition: class_pad.h:358
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
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:221
Module description (excepted pads)
const wxSize & GetSize() const
Definition: class_pad.h:284
EDGE_MODULE class definition.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void transformPadsShapesWithClearanceToPolygon(const PADS &aPads, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aCornerBuffer, int aInflateValue, bool aSkipNPTHPadsWihNoCopper) const
void buildPadShapePolygon(const D_PAD *aPad, SHAPE_POLY_SET &aCornerBuffer, wxSize aInflateValue) const
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)