KiCad PCB EDA Suite
board_items_to_polygon_shape_transform.cpp File Reference
#include <vector>
#include <fctsys.h>
#include <bezier_curves.h>
#include <base_units.h>
#include <draw_graphic_text.h>
#include <pcbnew.h>
#include <pcb_edit_frame.h>
#include <trigo.h>
#include <class_board.h>
#include <class_pad.h>
#include <class_track.h>
#include <class_drawsegment.h>
#include <class_pcb_text.h>
#include <class_zone.h>
#include <class_module.h>
#include <class_edge_mod.h>
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/geometry_utils.h>

Go to the source code of this file.

Classes

struct  TSEGM_2_POLY_PRMS
 

Functions

static void addTextSegmToPoly (int x0, int y0, int xf, int yf, void *aData)
 
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 thickness is min (dx/2, aCopperWitdh) or min (dy/2, aCopperWitdh) More...
 

Variables

TSEGM_2_POLY_PRMS prms
 
double s_error_max = Millimeter2iu( 0.02 )
 

Function Documentation

◆ addTextSegmToPoly()

static void addTextSegmToPoly ( int  x0,
int  y0,
int  xf,
int  yf,
void *  aData 
)
static

Definition at line 71 of file board_items_to_polygon_shape_transform.cpp.

72 {
73  TSEGM_2_POLY_PRMS* prm = static_cast<TSEGM_2_POLY_PRMS*>( aData );
75  wxPoint( x0, y0), wxPoint( xf, yf ),
77 }
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...

References TSEGM_2_POLY_PRMS::m_cornerBuffer, TSEGM_2_POLY_PRMS::m_textCircle2SegmentCount, TSEGM_2_POLY_PRMS::m_textWidth, and TransformRoundedEndsSegmentToPolygon().

Referenced by MODULE::TransformGraphicShapesWithClearanceToPolygonSet(), MODULE::TransformGraphicTextWithClearanceToPolygonSet(), and TEXTE_PCB::TransformShapeWithClearanceToPolygonSet().

◆ CreateThermalReliefPadPolygon()

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 thickness is min (dx/2, aCopperWitdh) or min (dy/2, aCopperWitdh)

Parameters
aCornerBuffer= a buffer to store the polygon
aPad= the current pad used to create the thermal shape
aThermalGap= gap in thermal shape
aCopperThickness= stubs thickness in thermal shape
aMinThicknessValue= min copper thickness allowed
aCircleToSegmentsCount= the number of segments to approximate a circle
aCorrectionFactor= the correction to apply to circles radius to keep
aThermalRot= for rond pads the rotation of thermal stubs (450 usually for 45 deg.)

Definition at line 929 of file board_items_to_polygon_shape_transform.cpp.

937 {
938  wxPoint corner, corner_end;
939  wxPoint padShapePos = aPad.ShapePos(); // Note: for pad having a shape offset,
940  // the pad position is NOT the shape position
941  wxSize copper_thickness;
942 
943  double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
944 
945  /* Keep in account the polygon outline thickness
946  * aThermalGap must be increased by aMinThicknessValue/2 because drawing external outline
947  * with a thickness of aMinThicknessValue will reduce gap by aMinThicknessValue/2
948  */
949  aThermalGap += aMinThicknessValue / 2;
950 
951  /* Keep in account the polygon outline thickness
952  * copper_thickness must be decreased by aMinThicknessValue because drawing outlines
953  * with a thickness of aMinThicknessValue will increase real thickness by aMinThicknessValue
954  */
955  int dx = aPad.GetSize().x / 2;
956  int dy = aPad.GetSize().y / 2;
957 
958  copper_thickness.x = std::min( aPad.GetSize().x, aCopperThickness ) - aMinThicknessValue;
959  copper_thickness.y = std::min( aPad.GetSize().y, aCopperThickness ) - aMinThicknessValue;
960 
961  if( copper_thickness.x < 0 )
962  copper_thickness.x = 0;
963 
964  if( copper_thickness.y < 0 )
965  copper_thickness.y = 0;
966 
967  switch( aPad.GetShape() )
968  {
969  case PAD_SHAPE_CIRCLE: // Add 4 similar holes
970  {
971  /* we create 4 copper holes and put them in position 1, 2, 3 and 4
972  * here is the area of the rectangular pad + its thermal gap
973  * the 4 copper holes remove the copper in order to create the thermal gap
974  * 4 ------ 1
975  * | |
976  * | |
977  * | |
978  * | |
979  * 3 ------ 2
980  * holes 2, 3, 4 are the same as hole 1, rotated 90, 180, 270 deg
981  */
982 
983  // Build the hole pattern, for the hole in the X >0, Y > 0 plane:
984  // The pattern roughtly is a 90 deg arc pie
985  std::vector <wxPoint> corners_buffer;
986 
987  // Radius of outer arcs of the shape corrected for arc approximation by lines
988  int outer_radius = KiROUND( (dx + aThermalGap) * aCorrectionFactor );
989 
990  // Crosspoint of thermal spoke sides, the first point of polygon buffer
991  corners_buffer.push_back( wxPoint( copper_thickness.x / 2, copper_thickness.y / 2 ) );
992 
993  // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side
994  // and first seg of arc approx
995  corner.x = copper_thickness.x / 2;
996  int y = outer_radius - (aThermalGap / 4);
997  corner.y = KiROUND( sqrt( ( (double) y * y - (double) corner.x * corner.x ) ) );
998 
999  if( aThermalRot != 0 )
1000  corners_buffer.push_back( corner );
1001 
1002  // calculate the starting point of the outter arc
1003  corner.x = copper_thickness.x / 2;
1004 
1005  corner.y = KiROUND( sqrt( ( (double) outer_radius * outer_radius ) -
1006  ( (double) corner.x * corner.x ) ) );
1007  RotatePoint( &corner, 90 ); // 9 degrees is the spoke fillet size
1008 
1009  // calculate the ending point of the outter arc
1010  corner_end.x = corner.y;
1011  corner_end.y = corner.x;
1012 
1013  // calculate intermediate points (y coordinate from corner.y to corner_end.y
1014  while( (corner.y > corner_end.y) && (corner.x < corner_end.x) )
1015  {
1016  corners_buffer.push_back( corner );
1017  RotatePoint( &corner, delta );
1018  }
1019 
1020  corners_buffer.push_back( corner_end );
1021 
1022  /* add an intermediate point, to avoid angles < 90 deg between last arc approx line
1023  * and radius line
1024  */
1025  corner.x = corners_buffer[1].y;
1026  corner.y = corners_buffer[1].x;
1027  corners_buffer.push_back( corner );
1028 
1029  // Now, add the 4 holes ( each is the pattern, rotated by 0, 90, 180 and 270 deg
1030  // aThermalRot = 450 (45.0 degrees orientation) work fine.
1031  double angle_pad = aPad.GetOrientation(); // Pad orientation
1032  double th_angle = aThermalRot;
1033 
1034  for( unsigned ihole = 0; ihole < 4; ihole++ )
1035  {
1036  aCornerBuffer.NewOutline();
1037 
1038  for( unsigned ii = 0; ii < corners_buffer.size(); ii++ )
1039  {
1040  corner = corners_buffer[ii];
1041  RotatePoint( &corner, th_angle + angle_pad ); // Rotate by segment angle and pad orientation
1042  corner += padShapePos;
1043  aCornerBuffer.Append( corner.x, corner.y );
1044  }
1045 
1046  th_angle += 900; // Note: th_angle in in 0.1 deg.
1047  }
1048  }
1049  break;
1050 
1051  case PAD_SHAPE_OVAL:
1052  {
1053  // Oval pad support along the lines of round and rectangular pads
1054  std::vector <wxPoint> corners_buffer; // Polygon buffer as vector
1055 
1056  dx = (aPad.GetSize().x / 2) + aThermalGap; // Cutout radius x
1057  dy = (aPad.GetSize().y / 2) + aThermalGap; // Cutout radius y
1058 
1059  wxPoint shape_offset;
1060 
1061  // We want to calculate an oval shape with dx > dy.
1062  // if this is not the case, exchange dx and dy, and rotate the shape 90 deg.
1063  int supp_angle = 0;
1064 
1065  if( dx < dy )
1066  {
1067  std::swap( dx, dy );
1068  supp_angle = 900;
1069  std::swap( copper_thickness.x, copper_thickness.y );
1070  }
1071 
1072  int deltasize = dx - dy; // = distance between shape position and the 2 demi-circle ends centre
1073  // here we have dx > dy
1074  // Radius of outer arcs of the shape:
1075  int outer_radius = dy; // The radius of the outer arc is radius end + aThermalGap
1076 
1077  // Some coordinate fiddling, depending on the shape offset direction
1078  shape_offset = wxPoint( deltasize, 0 );
1079 
1080  // Crosspoint of thermal spoke sides, the first point of polygon buffer
1081  corner.x = copper_thickness.x / 2;
1082  corner.y = copper_thickness.y / 2;
1083  corners_buffer.push_back( corner );
1084 
1085  // Arc start point calculation, the intersecting point of cutout arc and thermal spoke edge
1086  // If copper thickness is more than shape offset, we need to calculate arc intercept point.
1087  if( copper_thickness.x > deltasize )
1088  {
1089  corner.x = copper_thickness.x / 2;
1090  corner.y = KiROUND( sqrt( ( (double) outer_radius * outer_radius ) -
1091  ( (double) ( corner.x - delta ) * ( corner.x - deltasize ) ) ) );
1092  corner.x -= deltasize;
1093 
1094  /* creates an intermediate point, to have a > 90 deg angle
1095  * between the side and the first segment of arc approximation
1096  */
1097  wxPoint intpoint = corner;
1098  intpoint.y -= aThermalGap / 4;
1099  corners_buffer.push_back( intpoint + shape_offset );
1100  RotatePoint( &corner, 90 ); // 9 degrees of thermal fillet
1101  }
1102  else
1103  {
1104  corner.x = copper_thickness.x / 2;
1105  corner.y = outer_radius;
1106  corners_buffer.push_back( corner );
1107  }
1108 
1109  // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side
1110  // and first seg of arc approx
1111  wxPoint last_corner;
1112  last_corner.y = copper_thickness.y / 2;
1113  int px = outer_radius - (aThermalGap / 4);
1114  last_corner.x =
1115  KiROUND( sqrt( ( ( (double) px * px ) - (double) last_corner.y * last_corner.y ) ) );
1116 
1117  // Arc stop point calculation, the intersecting point of cutout arc and thermal spoke edge
1118  corner_end.y = copper_thickness.y / 2;
1119  corner_end.x =
1120  KiROUND( sqrt( ( (double) outer_radius *
1121  outer_radius ) - ( (double) corner_end.y * corner_end.y ) ) );
1122  RotatePoint( &corner_end, -90 ); // 9 degrees of thermal fillet
1123 
1124  // calculate intermediate arc points till limit is reached
1125  while( (corner.y > corner_end.y) && (corner.x < corner_end.x) )
1126  {
1127  corners_buffer.push_back( corner + shape_offset );
1128  RotatePoint( &corner, delta );
1129  }
1130 
1131  //corners_buffer.push_back(corner + shape_offset); // TODO: about one mil geometry error forms somewhere.
1132  corners_buffer.push_back( corner_end + shape_offset );
1133  corners_buffer.push_back( last_corner + shape_offset ); // Enabling the line above shows intersection point.
1134 
1135  /* Create 2 holes, rotated by pad rotation.
1136  */
1137  double angle = aPad.GetOrientation() + supp_angle;
1138 
1139  for( int irect = 0; irect < 2; irect++ )
1140  {
1141  aCornerBuffer.NewOutline();
1142  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1143  {
1144  wxPoint cpos = corners_buffer[ic];
1145  RotatePoint( &cpos, angle );
1146  cpos += padShapePos;
1147  aCornerBuffer.Append( cpos.x, cpos.y );
1148  }
1149 
1150  angle = AddAngles( angle, 1800 ); // this is calculate hole 3
1151  }
1152 
1153  // Create holes, that are the mirrored from the previous holes
1154  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1155  {
1156  wxPoint swap = corners_buffer[ic];
1157  swap.x = -swap.x;
1158  corners_buffer[ic] = swap;
1159  }
1160 
1161  // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
1162  angle = aPad.GetOrientation() + supp_angle;
1163 
1164  for( int irect = 0; irect < 2; irect++ )
1165  {
1166  aCornerBuffer.NewOutline();
1167 
1168  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1169  {
1170  wxPoint cpos = corners_buffer[ic];
1171  RotatePoint( &cpos, angle );
1172  cpos += padShapePos;
1173  aCornerBuffer.Append( cpos.x, cpos.y );
1174  }
1175 
1176  angle = AddAngles( angle, 1800 );
1177  }
1178  }
1179  break;
1180 
1182  case PAD_SHAPE_ROUNDRECT: // thermal shape is the same for rectangular shapes.
1183  case PAD_SHAPE_RECT:
1184  {
1185  /* we create 4 copper holes and put them in position 1, 2, 3 and 4
1186  * here is the area of the rectangular pad + its thermal gap
1187  * the 4 copper holes remove the copper in order to create the thermal gap
1188  * 1 ------ 4
1189  * | |
1190  * | |
1191  * | |
1192  * | |
1193  * 2 ------ 3
1194  * hole 3 is the same as hole 1, rotated 180 deg
1195  * hole 4 is the same as hole 2, rotated 180 deg and is the same as hole 1, mirrored
1196  */
1197 
1198  // First, create a rectangular hole for position 1 :
1199  // 2 ------- 3
1200  // | |
1201  // | |
1202  // | |
1203  // 1 -------4
1204 
1205  // Modified rectangles with one corner rounded. TODO: merging with oval thermals
1206  // and possibly round too.
1207 
1208  std::vector <wxPoint> corners_buffer; // Polygon buffer as vector
1209 
1210  dx = (aPad.GetSize().x / 2) + aThermalGap; // Cutout radius x
1211  dy = (aPad.GetSize().y / 2) + aThermalGap; // Cutout radius y
1212 
1213  // calculation is optimized for pad shape with dy >= dx (vertical rectangle).
1214  // if it is not the case, just rotate this shape 90 degrees:
1215  double angle = aPad.GetOrientation();
1216  wxPoint corner_origin_pos( -aPad.GetSize().x / 2, -aPad.GetSize().y / 2 );
1217 
1218  if( dy < dx )
1219  {
1220  std::swap( dx, dy );
1221  std::swap( copper_thickness.x, copper_thickness.y );
1222  std::swap( corner_origin_pos.x, corner_origin_pos.y );
1223  angle += 900.0;
1224  }
1225  // Now calculate the hole pattern in position 1 ( top left pad corner )
1226 
1227  // The first point of polygon buffer is left lower corner, second the crosspoint of
1228  // thermal spoke sides, the third is upper right corner and the rest are rounding
1229  // vertices going anticlockwise. Note the inverted Y-axis in corners_buffer y coordinates.
1230  wxPoint arc_end_point( -dx, -(aThermalGap / 4 + copper_thickness.y / 2) );
1231  corners_buffer.push_back( arc_end_point ); // Adds small miters to zone
1232  corners_buffer.push_back( wxPoint( -(dx - aThermalGap / 4), -copper_thickness.y / 2 ) ); // fill and spoke corner
1233  corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -copper_thickness.y / 2 ) );
1234  corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -(dy - aThermalGap / 4) ) );
1235  // The first point to build the rounded corner:
1236  wxPoint arc_start_point( -(aThermalGap / 4 + copper_thickness.x / 2) , -dy );
1237  corners_buffer.push_back( arc_start_point );
1238 
1239  int rounding_radius = KiROUND( aThermalGap * aCorrectionFactor ); // Corner rounding radius
1240 
1241  // Calculate arc angle parameters.
1242  // the start angle id near 900 decidegrees, the final angle is near 1800.0 decidegrees.
1243  double arc_increment = 3600.0 / aCircleToSegmentsCount;
1244 
1245  // the arc_angle_start is 900.0 or slighly more, depending on the actual arc starting point
1246  double arc_angle_start = atan2( -arc_start_point.y -corner_origin_pos.y, arc_start_point.x - corner_origin_pos.x ) * 1800/M_PI;
1247  if( arc_angle_start < 900.0 )
1248  arc_angle_start = 900.0;
1249 
1250  bool first_point = true;
1251  for( double curr_angle = arc_angle_start; ; curr_angle += arc_increment )
1252  {
1253  wxPoint corner_position = wxPoint( rounding_radius, 0 );
1254  RotatePoint( &corner_position, curr_angle ); // Rounding vector rotation
1255  corner_position += corner_origin_pos; // Rounding vector + Pad corner offset
1256 
1257  // The arc angle is <= 90 degrees, therefore the arc is finished if the x coordinate
1258  // decrease or the y coordinate is smaller than the y end point
1259  if( !first_point &&
1260  ( corner_position.x >= corners_buffer.back().x || corner_position.y > arc_end_point.y ) )
1261  break;
1262 
1263  first_point = false;
1264 
1265  // Note: for hole in position 1, arc x coordinate is always < x starting point
1266  // and arc y coordinate is always <= y ending point
1267  if( corner_position != corners_buffer.back() // avoid duplicate corners.
1268  && corner_position.x <= arc_start_point.x ) // skip current point at the right of the starting point
1269  corners_buffer.push_back( corner_position );
1270  }
1271 
1272  for( int irect = 0; irect < 2; irect++ )
1273  {
1274  aCornerBuffer.NewOutline();
1275 
1276  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1277  {
1278  wxPoint cpos = corners_buffer[ic];
1279  RotatePoint( &cpos, angle ); // Rotate according to module orientation
1280  cpos += padShapePos; // Shift origin to position
1281  aCornerBuffer.Append( cpos.x, cpos.y );
1282  }
1283 
1284  angle = AddAngles( angle, 1800 ); // this is calculate hole 3
1285  }
1286 
1287  // Create holes, that are the mirrored from the previous holes
1288  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1289  {
1290  wxPoint swap = corners_buffer[ic];
1291  swap.x = -swap.x;
1292  corners_buffer[ic] = swap;
1293  }
1294 
1295  // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
1296  for( int irect = 0; irect < 2; irect++ )
1297  {
1298  aCornerBuffer.NewOutline();
1299 
1300  for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
1301  {
1302  wxPoint cpos = corners_buffer[ic];
1303  RotatePoint( &cpos, angle );
1304  cpos += padShapePos;
1305  aCornerBuffer.Append( cpos.x, cpos.y );
1306  }
1307 
1308  angle = AddAngles( angle, 1800 );
1309  }
1310  }
1311  break;
1312 
1313  case PAD_SHAPE_TRAPEZOID:
1314  {
1315  SHAPE_POLY_SET antipad; // The full antipad area
1316 
1317  // We need a length to build the stubs of the thermal reliefs
1318  // the value is not very important. The pad bounding box gives a reasonable value
1319  EDA_RECT bbox = aPad.GetBoundingBox();
1320  int stub_len = std::max( bbox.GetWidth(), bbox.GetHeight() );
1321 
1322  aPad.TransformShapeWithClearanceToPolygon( antipad, aThermalGap,
1323  aCircleToSegmentsCount, aCorrectionFactor );
1324 
1325  SHAPE_POLY_SET stub; // A basic stub ( a rectangle)
1326  SHAPE_POLY_SET stubs; // the full stubs shape
1327 
1328 
1329  // We now substract the stubs (connections to the copper zone)
1330  //ClipperLib::Clipper clip_engine;
1331  // Prepare a clipping transform
1332  //clip_engine.AddPath( antipad, ClipperLib::ptSubject, true );
1333 
1334  // Create stubs and add them to clipper engine
1335  wxPoint stubBuffer[4];
1336  stubBuffer[0].x = stub_len;
1337  stubBuffer[0].y = copper_thickness.y/2;
1338  stubBuffer[1] = stubBuffer[0];
1339  stubBuffer[1].y = -copper_thickness.y/2;
1340  stubBuffer[2] = stubBuffer[1];
1341  stubBuffer[2].x = -stub_len;
1342  stubBuffer[3] = stubBuffer[2];
1343  stubBuffer[3].y = copper_thickness.y/2;
1344 
1345  stub.NewOutline();
1346 
1347  for( unsigned ii = 0; ii < arrayDim( stubBuffer ); ii++ )
1348  {
1349  wxPoint cpos = stubBuffer[ii];
1350  RotatePoint( &cpos, aPad.GetOrientation() );
1351  cpos += padShapePos;
1352  stub.Append( cpos.x, cpos.y );
1353  }
1354 
1355  stubs.Append( stub );
1356 
1357  stubBuffer[0].y = stub_len;
1358  stubBuffer[0].x = copper_thickness.x/2;
1359  stubBuffer[1] = stubBuffer[0];
1360  stubBuffer[1].x = -copper_thickness.x/2;
1361  stubBuffer[2] = stubBuffer[1];
1362  stubBuffer[2].y = -stub_len;
1363  stubBuffer[3] = stubBuffer[2];
1364  stubBuffer[3].x = copper_thickness.x/2;
1365 
1366  stub.RemoveAllContours();
1367  stub.NewOutline();
1368 
1369  for( unsigned ii = 0; ii < arrayDim( stubBuffer ); ii++ )
1370  {
1371  wxPoint cpos = stubBuffer[ii];
1372  RotatePoint( &cpos, aPad.GetOrientation() );
1373  cpos += padShapePos;
1374  stub.Append( cpos.x, cpos.y );
1375  }
1376 
1377  stubs.Append( stub );
1379 
1380  antipad.BooleanSubtract( stubs, SHAPE_POLY_SET::PM_FAST );
1381  aCornerBuffer.Append( antipad );
1382 
1383  break;
1384  }
1385 
1386  default:
1387  ;
1388  }
1389 }
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:118
int GetWidth() const
Definition: eda_rect.h:117
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
static const int delta[8][2]
Definition: solve.cpp:112
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor, bool ignoreLineWidth=false) const override
Function TransformShapeWithClearanceToPolygon Convert the pad shape to a closed polygon Used in filli...
T AddAngles(T a1, T2 a2)
Add two angles (keeping the result normalized). T2 is here.
Definition: trigo.h:297
Class SHAPE_POLY_SET.
void Simplify(POLYGON_MODE aFastMode)
Simplifies the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFast...
int NewOutline()
Creates a new empty polygon in the set and returns its index
int GetHeight() const
Definition: eda_rect.h:118
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:107
#define max(a, b)
Definition: auxiliary.h:86
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:394
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
wxPoint ShapePos() const
Definition: class_pad.cpp:562
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset difference For aFastMode meaning, see function booleanOp
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:218
const wxSize & GetSize() const
Definition: class_pad.h:271
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: class_pad.cpp:226
#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)

References AddAngles(), PNS::angle(), SHAPE_POLY_SET::Append(), arrayDim(), SHAPE_POLY_SET::BooleanSubtract(), delta, D_PAD::GetBoundingBox(), EDA_RECT::GetHeight(), D_PAD::GetOrientation(), D_PAD::GetShape(), D_PAD::GetSize(), EDA_RECT::GetWidth(), KiROUND(), max, min, SHAPE_POLY_SET::NewOutline(), PAD_SHAPE_CHAMFERED_RECT, PAD_SHAPE_CIRCLE, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, SHAPE_POLY_SET::PM_FAST, SHAPE_POLY_SET::RemoveAllContours(), RotatePoint(), D_PAD::ShapePos(), SHAPE_POLY_SET::Simplify(), and D_PAD::TransformShapeWithClearanceToPolygon().

Referenced by ZONE_FILLER::buildZoneFeatureHoleList().

Variable Documentation

◆ prms

◆ s_error_max

double s_error_max = Millimeter2iu( 0.02 )