Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
4bba4b87
Commit
4bba4b87
authored
Nov 29, 2014
by
jean-pierre charras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pcbnew: Allows trapezoidal pads in zones.
parent
f4ca3d55
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
137 additions
and
75 deletions
+137
-75
board_items_to_polygon_shape_transform.cpp
pcbnew/board_items_to_polygon_shape_transform.cpp
+136
-70
zones_convert_brd_items_to_polygons_with_Boost.cpp
pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
+1
-5
No files found.
pcbnew/board_items_to_polygon_shape_transform.cpp
View file @
4bba4b87
...
...
@@ -27,8 +27,8 @@
* @brief function to convert shapes of items ( pads, tracks... ) to polygons
*/
/* Function to convert pad
s and tran
ck shapes to polygons
* Used to fill zones areas
/* Function to convert pad
and tra
ck shapes to polygons
* Used to fill zones areas
and in 3D viewer
*/
#include <vector>
...
...
@@ -520,22 +520,19 @@ void TRACK:: TransformShapeWithClearanceToPolygon( CPOLYGONS_LIST& aCornerBuffer
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
*/
#include <clipper.hpp>
void
D_PAD
::
TransformShapeWithClearanceToPolygon
(
CPOLYGONS_LIST
&
aCornerBuffer
,
int
aClearanceValue
,
int
aCircleToSegmentsCount
,
double
aCorrectionFactor
)
const
{
wxPoint
corner_position
;
double
angle
;
double
angle
=
m_Orient
;
int
dx
=
(
m_Size
.
x
/
2
)
+
aClearanceValue
;
int
dy
=
(
m_Size
.
y
/
2
)
+
aClearanceValue
;
double
delta
=
3600.0
/
aCircleToSegmentsCount
;
// rot angle in 0.1 degree
wxPoint
PadShapePos
=
ShapePos
();
/* Note: for pad having a shape offset,
wxPoint
PadShapePos
=
ShapePos
();
/* Note: for pad having a shape offset,
* the pad position is NOT the shape position */
wxSize
psize
=
m_Size
;
/* pad size unsed in RECT and TRAPEZOIDAL pads
* trapezoidal pads are considered as rect
* pad shape having they boudary box size */
switch
(
GetShape
()
)
{
...
...
@@ -547,7 +544,6 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( CPOLYGONS_LIST& aCornerBuffer
case
PAD_OVAL
:
// An oval pad has the same shape as a segment with rounded ends
angle
=
m_Orient
;
{
int
width
;
wxPoint
shape_offset
;
...
...
@@ -573,77 +569,51 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( CPOLYGONS_LIST& aCornerBuffer
break
;
case
PAD_TRAPEZOID
:
psize
.
x
+=
std
::
abs
(
m_DeltaSize
.
y
);
psize
.
y
+=
std
::
abs
(
m_DeltaSize
.
x
);
// fall through
case
PAD_RECT
:
// Easy implementation for rectangular cutouts with rounded corners
angle
=
m_Orient
;
// Corner rounding radius
int
rounding_radius
=
KiROUND
(
aClearanceValue
*
aCorrectionFactor
);
double
angle_pg
;
// Polygon increment angle
for
(
int
i
=
0
;
i
<
aCircleToSegmentsCount
/
4
+
1
;
i
++
)
{
corner_position
=
wxPoint
(
0
,
-
rounding_radius
);
RotatePoint
(
&
corner_position
,
(
1800.0
/
aCircleToSegmentsCount
)
);
// Start at half increment offset
angle_pg
=
i
*
delta
;
RotatePoint
(
&
corner_position
,
angle_pg
);
// Rounding vector rotation
corner_position
-=
psize
/
2
;
// Rounding vector + Pad corner offset
RotatePoint
(
&
corner_position
,
angle
);
// Rotate according to module orientation
corner_position
+=
PadShapePos
;
// Shift origin to position
CPolyPt
polypoint
(
corner_position
.
x
,
corner_position
.
y
);
aCornerBuffer
.
Append
(
polypoint
);
}
for
(
int
i
=
0
;
i
<
aCircleToSegmentsCount
/
4
+
1
;
i
++
)
{
corner_position
=
wxPoint
(
-
rounding_radius
,
0
);
RotatePoint
(
&
corner_position
,
(
1800.0
/
aCircleToSegmentsCount
)
);
angle_pg
=
i
*
delta
;
RotatePoint
(
&
corner_position
,
angle_pg
);
corner_position
-=
wxPoint
(
psize
.
x
/
2
,
-
psize
.
y
/
2
);
RotatePoint
(
&
corner_position
,
angle
);
corner_position
+=
PadShapePos
;
CPolyPt
polypoint
(
corner_position
.
x
,
corner_position
.
y
);
aCornerBuffer
.
Append
(
polypoint
);
}
{
wxPoint
corners
[
4
];
BuildPadPolygon
(
corners
,
wxSize
(
0
,
0
),
angle
);
for
(
int
i
=
0
;
i
<
aCircleToSegmentsCount
/
4
+
1
;
i
++
)
{
corner_position
=
wxPoint
(
0
,
rounding_radius
);
RotatePoint
(
&
corner_position
,
(
1800.0
/
aCircleToSegmentsCount
)
);
angle_pg
=
i
*
delta
;
RotatePoint
(
&
corner_position
,
angle_pg
);
corner_position
+=
psize
/
2
;
RotatePoint
(
&
corner_position
,
angle
);
corner_position
+=
PadShapePos
;
CPolyPt
polypoint
(
corner_position
.
x
,
corner_position
.
y
);
aCornerBuffer
.
Append
(
polypoint
);
}
// We are using ClipperLib to inflate the polygon shape, using
// arcs to connect moved segments.
ClipperLib
::
Path
outline
;
ClipperLib
::
Paths
shapeWithClearance
;
for
(
int
i
=
0
;
i
<
aCircleToSegmentsCount
/
4
+
1
;
i
++
)
for
(
int
ii
=
0
;
ii
<
4
;
ii
++
)
outline
<<
ClipperLib
::
IntPoint
(
corners
[
ii
].
x
,
corners
[
ii
].
y
);
ClipperLib
::
ClipperOffset
offset_engine
;
// Prepare an offset (inflate) transform, with edges connected by arcs
offset_engine
.
AddPath
(
outline
,
ClipperLib
::
jtRound
,
ClipperLib
::
etClosedPolygon
);
// Clipper approximates arcs by segments
// It uses a value called ArcTolerance which is the max error between the arc
// and segments created to approximate this arc
// the number of segm per circle is:
// n = PI / acos(1 - arc_tolerance / (arc radius))
// the arc radius is aClearanceValue
// because arc_tolerance is << aClearanceValue and aClearanceValue >= 0
// n = PI / (arc_tolerance / aClearanceValue )
offset_engine
.
ArcTolerance
=
(
double
)
aClearanceValue
/
3.14
/
aCircleToSegmentsCount
;
double
rounding_radius
=
aClearanceValue
*
aCorrectionFactor
;
offset_engine
.
Execute
(
shapeWithClearance
,
rounding_radius
);
// get new outline (only one polygon is expected)
// For info, ClipperLib uses long long to handle integer coordinates
ClipperLib
::
Path
&
polygon
=
shapeWithClearance
[
0
];
for
(
unsigned
jj
=
0
;
jj
<
polygon
.
size
();
jj
++
)
{
corner_position
=
wxPoint
(
rounding_radius
,
0
);
RotatePoint
(
&
corner_position
,
(
1800.0
/
aCircleToSegmentsCount
)
);
angle_pg
=
i
*
delta
;
RotatePoint
(
&
corner_position
,
angle_pg
);
corner_position
-=
wxPoint
(
-
psize
.
x
/
2
,
psize
.
y
/
2
);
RotatePoint
(
&
corner_position
,
angle
);
corner_position
.
x
=
int
(
polygon
[
jj
].
X
);
corner_position
.
y
=
int
(
polygon
[
jj
].
Y
);
corner_position
+=
PadShapePos
;
CPolyPt
polypoint
(
corner_position
.
x
,
corner_position
.
y
);
aCornerBuffer
.
Append
(
polypoint
);
}
aCornerBuffer
.
CloseLastContour
();
}
break
;
}
}
...
...
@@ -1090,9 +1060,105 @@ void CreateThermalReliefPadPolygon( CPOLYGONS_LIST& aCornerBuffer,
aCornerBuffer
.
CloseLastContour
();
angle
=
AddAngles
(
angle
,
1800
);
}
}
break
;
case
PAD_TRAPEZOID
:
{
CPOLYGONS_LIST
cbuffer
;
// We need a length to build the stubs of the thermal reliefs
// the value is not very important. The pad bounding box gives a reasonable value
EDA_RECT
bbox
=
aPad
.
GetBoundingBox
();
int
stub_len
=
std
::
max
(
bbox
.
GetWidth
(),
bbox
.
GetHeight
()
);
aPad
.
TransformShapeWithClearanceToPolygon
(
cbuffer
,
aThermalGap
,
aCircleToSegmentsCount
,
aCorrectionFactor
);
// We are using ClipperLib to substract stubs to clearance area (antipad area).
ClipperLib
::
Path
antipad
;
// The full antipad area
ClipperLib
::
Path
stub
;
// A basic stub ( a rectangle)
ClipperLib
::
Paths
stubs
;
// the full stubs shape
ClipperLib
::
Paths
thermalShape
;
// the holes in copper zone
// cbuffer is expected to contain only one polygon, which is
// area of the pad + the thermal gap (the antipad)
for
(
unsigned
ii
=
0
;
ii
<
cbuffer
.
GetCornersCount
();
ii
++
)
antipad
<<
ClipperLib
::
IntPoint
(
cbuffer
.
GetPos
(
ii
).
x
,
cbuffer
.
GetPos
(
ii
).
y
);
// We now substract the stubs (connections to the copper zone)
ClipperLib
::
Clipper
clip_engine
;
// Prepare a clipping transform
clip_engine
.
AddPath
(
antipad
,
ClipperLib
::
ptSubject
,
true
);
// Create stubs and add them to clipper engine
wxPoint
stubBuffer
[
4
];
stubBuffer
[
0
].
x
=
stub_len
;
stubBuffer
[
0
].
y
=
copper_thickness
.
y
/
2
;
stubBuffer
[
1
]
=
stubBuffer
[
0
];
stubBuffer
[
1
].
y
=
-
copper_thickness
.
y
/
2
;
stubBuffer
[
2
]
=
stubBuffer
[
1
];
stubBuffer
[
2
].
x
=
-
stub_len
;
stubBuffer
[
3
]
=
stubBuffer
[
2
];
stubBuffer
[
3
].
y
=
copper_thickness
.
y
/
2
;
for
(
unsigned
ii
=
0
;
ii
<
DIM
(
stubBuffer
);
ii
++
)
{
wxPoint
cpos
=
stubBuffer
[
ii
];
RotatePoint
(
&
cpos
,
aPad
.
GetOrientation
()
);
cpos
+=
PadShapePos
;
stub
<<
ClipperLib
::
IntPoint
(
cpos
.
x
,
cpos
.
y
);
}
ClipperLib
::
Clipper
stubs_engine
;
stubs_engine
.
AddPath
(
stub
,
ClipperLib
::
ptSubject
,
true
);
stubBuffer
[
0
].
y
=
stub_len
;
stubBuffer
[
0
].
x
=
copper_thickness
.
x
/
2
;
stubBuffer
[
1
]
=
stubBuffer
[
0
];
stubBuffer
[
1
].
x
=
-
copper_thickness
.
x
/
2
;
stubBuffer
[
2
]
=
stubBuffer
[
1
];
stubBuffer
[
2
].
y
=
-
stub_len
;
stubBuffer
[
3
]
=
stubBuffer
[
2
];
stubBuffer
[
3
].
x
=
copper_thickness
.
x
/
2
;
stub
.
clear
();
for
(
unsigned
ii
=
0
;
ii
<
DIM
(
stubBuffer
);
ii
++
)
{
wxPoint
cpos
=
stubBuffer
[
ii
];
RotatePoint
(
&
cpos
,
aPad
.
GetOrientation
()
);
cpos
+=
PadShapePos
;
stub
<<
ClipperLib
::
IntPoint
(
cpos
.
x
,
cpos
.
y
);
}
stubs_engine
.
AddPath
(
stub
,
ClipperLib
::
ptClip
,
true
);
// Build the full stubs shape:
stubs_engine
.
Execute
(
ClipperLib
::
ctUnion
,
stubs
);
// remove stubs to antipad area (i.e. add copper stubs)
clip_engine
.
AddPath
(
stubs
[
0
],
ClipperLib
::
ptClip
,
true
);
clip_engine
.
Execute
(
ClipperLib
::
ctDifference
,
thermalShape
);
// put thermal shapes (holes) to list:
wxPoint
corner_position
;
for
(
unsigned
ii
=
0
;
ii
<
thermalShape
.
size
();
ii
++
)
{
ClipperLib
::
Path
&
polygon
=
thermalShape
[
ii
];
for
(
unsigned
jj
=
0
;
jj
<
polygon
.
size
();
jj
++
)
{
corner_position
.
x
=
int
(
polygon
[
jj
].
X
);
corner_position
.
y
=
int
(
polygon
[
jj
].
Y
);
CPolyPt
polypoint
(
corner_position
.
x
,
corner_position
.
y
);
aCornerBuffer
.
Append
(
polypoint
);
}
aCornerBuffer
.
CloseLastContour
();
}
break
;
}
default
:
;
...
...
pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
View file @
4bba4b87
...
...
@@ -249,11 +249,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
continue
;
}
if
(
(
GetPadConnection
(
pad
)
==
PAD_NOT_IN_ZONE
)
||
(
pad
->
GetShape
()
==
PAD_TRAPEZOID
)
)
// PAD_TRAPEZOID shapes are not in zones because they are used in microwave apps
// and i think it is good that shapes are not changed by thermal pads or others
if
(
GetPadConnection
(
pad
)
==
PAD_NOT_IN_ZONE
)
{
int
gap
=
zone_clearance
;
int
thermalGap
=
GetThermalReliefGap
(
pad
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment