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
d54ade94
Commit
d54ade94
authored
May 17, 2014
by
jean-pierre charras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rework on DXF export.
parent
073a9e17
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
292 additions
and
53 deletions
+292
-53
3d_draw.cpp
3d-viewer/3d_draw.cpp
+1
-1
gr_basic.cpp
common/gr_basic.cpp
+1
-1
board_items_to_polygon_shape_transform.cpp
pcbnew/board_items_to_polygon_shape_transform.cpp
+82
-24
class_board.h
pcbnew/class_board.h
+13
-0
class_pad.cpp
pcbnew/class_pad.cpp
+33
-0
class_pad.h
pcbnew/class_pad.h
+11
-0
class_pad_draw_functions.cpp
pcbnew/class_pad_draw_functions.cpp
+6
-22
pcbplot.h
pcbnew/pcbplot.h
+11
-0
plot_board_layers.cpp
pcbnew/plot_board_layers.cpp
+134
-5
No files found.
3d-viewer/3d_draw.cpp
View file @
d54ade94
...
...
@@ -239,7 +239,7 @@ void EDA_3D_CANVAS::BuildBoard3DView()
BOARD
*
pcb
=
GetBoard
();
bool
realistic_mode
=
g_Parm_3D_Visu
.
IsRealisticMode
();
// Number of segments to
draw a circle using segments
// Number of segments to
convert a circle to polygon
const
int
segcountforcircle
=
16
;
double
correctionFactor
=
1.0
/
cos
(
M_PI
/
(
segcountforcircle
*
2
)
);
const
int
segcountLowQuality
=
12
;
// segments to draw a circle with low quality
...
...
common/gr_basic.cpp
View file @
d54ade94
...
...
@@ -848,7 +848,7 @@ static void GRSClosedPoly( EDA_RECT* aClipBox, wxDC* aDC,
// Close the polygon
if
(
aPoints
[
lastpt
]
!=
aPoints
[
0
]
)
{
GRLineTo
(
aClipBox
,
aDC
,
aPoints
[
lastpt
].
x
,
aPoints
[
lastpt
].
y
,
aWidth
,
aColor
);
GRLineTo
(
aClipBox
,
aDC
,
aPoints
[
0
].
x
,
aPoints
[
0
].
y
,
aWidth
,
aColor
);
}
}
}
...
...
pcbnew/board_items_to_polygon_shape_transform.cpp
View file @
d54ade94
...
...
@@ -14,6 +14,7 @@
#include <pcbnew.h>
#include <wxPcbStruct.h>
#include <trigo.h>
#include <class_board.h>
#include <class_pad.h>
#include <class_track.h>
#include <class_drawsegment.h>
...
...
@@ -38,6 +39,80 @@ static void addTextSegmToPoly( int x0, int y0, int xf, int yf )
s_textCircle2SegmentCount
,
s_textWidth
);
}
/**
* Function ConvertBrdLayerToPolygonalContours
* Build a set of polygons which are the outlines of copper items
* (pads, tracks, texts, zones)
* the holes in vias or pads are ignored
* Usefull to export the shape of copper layers to dxf polygons
* or 3D viewer
* the polygons are not merged.
* @param aLayer = A layer, like LAYER_N_BACK, etc.
* @param aOutlines The CPOLYGONS_LIST to fill in with main outlines.
* @return true if success, false if a contour is not valid
*/
void
BOARD
::
ConvertBrdLayerToPolygonalContours
(
LAYER_NUM
aLayer
,
CPOLYGONS_LIST
&
aOutlines
)
{
// Number of segments to convert a circle to a polygon
const
int
segcountforcircle
=
16
;
double
correctionFactor
=
1.0
/
cos
(
M_PI
/
(
segcountforcircle
*
2
)
);
// convert tracks and vias:
for
(
TRACK
*
track
=
m_Track
;
track
!=
NULL
;
track
=
track
->
Next
()
)
{
if
(
!
track
->
IsOnLayer
(
aLayer
)
)
continue
;
track
->
TransformShapeWithClearanceToPolygon
(
aOutlines
,
0
,
segcountforcircle
,
correctionFactor
);
}
// convert pads
for
(
MODULE
*
module
=
m_Modules
;
module
!=
NULL
;
module
=
module
->
Next
()
)
{
module
->
TransformPadsShapesWithClearanceToPolygon
(
aLayer
,
aOutlines
,
0
,
segcountforcircle
,
correctionFactor
);
// Micro-wave modules may have items on copper layers
module
->
TransformGraphicShapesWithClearanceToPolygonSet
(
aLayer
,
aOutlines
,
0
,
segcountforcircle
,
correctionFactor
);
}
// convert copper zones
for
(
int
ii
=
0
;
ii
<
GetAreaCount
();
ii
++
)
{
ZONE_CONTAINER
*
zone
=
GetArea
(
ii
);
LAYER_NUM
zonelayer
=
zone
->
GetLayer
();
if
(
zonelayer
==
aLayer
)
zone
->
TransformSolidAreasShapesToPolygonSet
(
aOutlines
,
segcountforcircle
,
correctionFactor
);
}
// convert graphic items on copper layers (texts)
for
(
BOARD_ITEM
*
item
=
m_Drawings
;
item
;
item
=
item
->
Next
()
)
{
if
(
!
item
->
IsOnLayer
(
aLayer
)
)
continue
;
switch
(
item
->
Type
()
)
{
case
PCB_LINE_T
:
// should not exist on copper layers
(
(
DRAWSEGMENT
*
)
item
)
->
TransformShapeWithClearanceToPolygon
(
aOutlines
,
0
,
segcountforcircle
,
correctionFactor
);
break
;
case
PCB_TEXT_T
:
(
(
TEXTE_PCB
*
)
item
)
->
TransformShapeWithClearanceToPolygonSet
(
aOutlines
,
0
,
segcountforcircle
,
correctionFactor
);
break
;
default
:
break
;
}
}
}
/* generate pads shapes on layer aLayer as polygons,
* and adds these polygons to aCornerBuffer
* aCornerBuffer = the buffer to store polygons
...
...
@@ -614,43 +689,26 @@ bool D_PAD::BuildPadDrillShapePolygon( CPOLYGONS_LIST& aCornerBuffer,
int
aInflateValue
,
int
aSegmentsPerCircle
)
const
{
wxSize
drillsize
=
GetDrillSize
();
bool
hasHole
=
drillsize
.
x
&&
drillsize
.
y
;
if
(
!
hasHole
)
if
(
!
drillsize
.
x
||
!
drillsize
.
y
)
return
false
;
drillsize
.
x
+=
aInflateValue
;
drillsize
.
y
+=
aInflateValue
;
if
(
drillsize
.
x
==
drillsize
.
y
)
// usual round hole
{
TransformCircleToPolygon
(
aCornerBuffer
,
GetPosition
(),
drillsize
.
x
/
2
,
aSegmentsPerCircle
);
(
drillsize
.
x
/
2
)
+
aInflateValue
,
aSegmentsPerCircle
);
}
else
// Oblong hole
{
wxPoint
ends_offset
;
wxPoint
start
,
end
;
int
width
;
if
(
drillsize
.
x
>
drillsize
.
y
)
// Horizontal oval
{
ends_offset
.
x
=
(
drillsize
.
x
-
drillsize
.
y
)
/
2
;
width
=
drillsize
.
y
;
}
else
// Vertical oval
{
ends_offset
.
y
=
(
drillsize
.
y
-
drillsize
.
x
)
/
2
;
width
=
drillsize
.
x
;
}
RotatePoint
(
&
ends_offset
,
GetOrientation
()
);
GetOblongDrillGeometry
(
start
,
end
,
width
);
wxPoint
start
=
GetPosition
()
+
ends_offset
;
wxPoint
end
=
GetPosition
()
-
ends_offset
;
width
+=
aInflateValue
*
2
;
// Prepare the shape creation
TransformRoundedEndsSegmentToPolygon
(
aCornerBuffer
,
start
,
end
,
aSegmentsPerCircle
,
width
);
TransformRoundedEndsSegmentToPolygon
(
aCornerBuffer
,
GetPosition
()
+
start
,
GetPosition
()
+
end
,
aSegmentsPerCircle
,
width
);
}
return
true
;
...
...
pcbnew/class_board.h
View file @
d54ade94
...
...
@@ -685,6 +685,19 @@ public:
CPOLYGONS_LIST
&
aHoles
,
wxString
*
aErrorText
=
NULL
);
/**
* Function ConvertBrdLayerToPolygonalContours
* Build a set of polygons which are the outlines of copper items
* (pads, tracks, vias, texts, zones)
* Holes in vias or pads are ignored
* Usefull to export the shape of copper layers to dxf polygons
* or 3D viewer
* the polygons are not merged.
* @param aLayer = A copper layer, like LAYER_N_BACK, etc.
* @param aOutlines The CPOLYGONS_LIST to fill in with items outline.
*/
void
ConvertBrdLayerToPolygonalContours
(
LAYER_NUM
aLayer
,
CPOLYGONS_LIST
&
aOutlines
);
/**
* Function GetLayerName
* returns the name of a layer given by aLayer. Copper layers may
...
...
pcbnew/class_pad.cpp
View file @
d54ade94
...
...
@@ -637,6 +637,39 @@ bool D_PAD::IsOnLayer( LAYER_NUM aLayer ) const
}
void
D_PAD
::
GetOblongDrillGeometry
(
wxPoint
&
aStartPoint
,
wxPoint
&
aEndPoint
,
int
&
aWidth
)
const
{
// calculates the start point, end point and width
// of an equivalent segment which have the same position and width as the hole
int
delta_cx
,
delta_cy
;
wxSize
halfsize
=
GetDrillSize
();;
halfsize
.
x
/=
2
;
halfsize
.
y
/=
2
;
if
(
m_Drill
.
x
>
m_Drill
.
y
)
// horizontal
{
delta_cx
=
halfsize
.
x
-
halfsize
.
y
;
delta_cy
=
0
;
aWidth
=
m_Drill
.
y
;
}
else
// vertical
{
delta_cx
=
0
;
delta_cy
=
halfsize
.
y
-
halfsize
.
x
;
aWidth
=
m_Drill
.
x
;
}
RotatePoint
(
&
delta_cx
,
&
delta_cy
,
m_Orient
);
aStartPoint
.
x
=
delta_cx
;
aStartPoint
.
y
=
delta_cy
;
aEndPoint
.
x
=
-
delta_cx
;
aEndPoint
.
y
=
-
delta_cy
;
}
bool
D_PAD
::
HitTest
(
const
wxPoint
&
aPosition
)
const
{
int
dx
,
dy
;
...
...
pcbnew/class_pad.h
View file @
d54ade94
...
...
@@ -169,6 +169,17 @@ public:
{
m_drillShape
=
aDrillShape
;
}
PAD_DRILL_SHAPE_T
GetDrillShape
()
const
{
return
m_drillShape
;
}
/**
* Function GetOblongDrillGeometry calculates the start point, end point and width
* of an equivalent segment which have the same position and width as the hole
* Usefull to plot/draw oblong holes like segments with rounded ends
* used in draw and plot functions
* @param aStartPoint = first point of the equivalent segment, relative to the pad position.
* @param aEndPoint = second point of the equivalent segment, relative to the pad position.
* @param aWidth = width equivalent segment.
*/
void
GetOblongDrillGeometry
(
wxPoint
&
aStartPoint
,
wxPoint
&
aEndPoint
,
int
&
aWidth
)
const
;
void
SetLayerMask
(
LAYER_MSK
aLayerMask
)
{
m_layerMask
=
aLayerMask
;
}
LAYER_MSK
GetLayerMask
()
const
{
return
m_layerMask
;
}
...
...
pcbnew/class_pad_draw_functions.cpp
View file @
d54ade94
...
...
@@ -310,7 +310,6 @@ void D_PAD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDraw_mode,
void
D_PAD
::
DrawShape
(
EDA_RECT
*
aClipBox
,
wxDC
*
aDC
,
PAD_DRAWINFO
&
aDrawInfo
)
{
wxPoint
coord
[
4
];
int
delta_cx
,
delta_cy
;
double
angle
=
m_Orient
;
int
seg_width
;
...
...
@@ -439,27 +438,12 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
break
;
case
PAD_DRILL_OBLONG
:
halfsize
.
x
=
m_Drill
.
x
>>
1
;
halfsize
.
y
=
m_Drill
.
y
>>
1
;
if
(
m_Drill
.
x
>
m_Drill
.
y
)
// horizontal
{
delta_cx
=
halfsize
.
x
-
halfsize
.
y
;
delta_cy
=
0
;
seg_width
=
m_Drill
.
y
;
}
else
// vertical
{
delta_cx
=
0
;
delta_cy
=
halfsize
.
y
-
halfsize
.
x
;
seg_width
=
m_Drill
.
x
;
wxPoint
drl_start
,
drl_end
;
GetOblongDrillGeometry
(
drl_start
,
drl_end
,
seg_width
);
GRFilledSegment
(
aClipBox
,
aDC
,
holepos
+
drl_start
,
holepos
+
drl_end
,
seg_width
,
hole_color
);
}
RotatePoint
(
&
delta_cx
,
&
delta_cy
,
angle
);
GRFillCSegm
(
aClipBox
,
aDC
,
holepos
.
x
+
delta_cx
,
holepos
.
y
+
delta_cy
,
holepos
.
x
-
delta_cx
,
holepos
.
y
-
delta_cy
,
seg_width
,
hole_color
);
break
;
default
:
...
...
pcbnew/pcbplot.h
View file @
d54ade94
...
...
@@ -204,6 +204,17 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, LAYER_NUM aLayer,
void
PlotStandardLayer
(
BOARD
*
aBoard
,
PLOTTER
*
aPlotter
,
LAYER_MSK
aLayerMask
,
const
PCB_PLOT_PARAMS
&
aPlotOpt
);
/**
* Function PlotLayerOutlines
* plot copper outline of a copper layer.
* @param aBoard = the board to plot
* @param aPlotter = the plotter to use
* @param aLayerMask = the mask to define the layers to plot
* @param aPlotOpt = the plot options. Has meaning for some formats only
*/
void
PlotLayerOutlines
(
BOARD
*
aBoard
,
PLOTTER
*
aPlotter
,
LAYER_MSK
aLayerMask
,
const
PCB_PLOT_PARAMS
&
aPlotOpt
);
/**
* Function PlotSilkScreen
* plot silkscreen layers which have specific requirements, mainly for pads.
...
...
pcbnew/plot_board_layers.cpp
View file @
d54ade94
...
...
@@ -176,10 +176,18 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, LAYER_NUM aLayer,
case
LAYER_N_15
:
case
LAST_COPPER_LAYER
:
// Skip NPTH pads on copper layers ( only if hole size == pad size ):
plotOpt
.
SetSkipPlotNPTH_Pads
(
true
);
// Drill mark will be plotted,
// if drill mark is SMALL_DRILL_SHAPE or FULL_DRILL_SHAPE
if
(
plotOpt
.
GetFormat
()
==
PLOT_FORMAT_DXF
)
{
plotOpt
.
SetSkipPlotNPTH_Pads
(
false
);
PlotLayerOutlines
(
aBoard
,
aPlotter
,
layer_mask
,
plotOpt
);
}
else
{
plotOpt
.
SetSkipPlotNPTH_Pads
(
true
);
PlotStandardLayer
(
aBoard
,
aPlotter
,
layer_mask
,
plotOpt
);
}
break
;
case
SOLDERMASK_N_BACK
:
...
...
@@ -190,7 +198,12 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, LAYER_NUM aLayer,
// Plot solder mask:
if
(
soldermask_min_thickness
==
0
)
{
if
(
plotOpt
.
GetFormat
()
==
PLOT_FORMAT_DXF
)
PlotLayerOutlines
(
aBoard
,
aPlotter
,
layer_mask
,
plotOpt
);
else
PlotStandardLayer
(
aBoard
,
aPlotter
,
layer_mask
,
plotOpt
);
}
else
PlotSolderMaskLayer
(
aBoard
,
aPlotter
,
layer_mask
,
plotOpt
,
soldermask_min_thickness
);
...
...
@@ -202,11 +215,18 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, LAYER_NUM aLayer,
plotOpt
.
SetSkipPlotNPTH_Pads
(
false
);
// Disable plot pad holes
plotOpt
.
SetDrillMarksType
(
PCB_PLOT_PARAMS
::
NO_DRILL_SHAPE
);
if
(
plotOpt
.
GetFormat
()
==
PLOT_FORMAT_DXF
)
PlotLayerOutlines
(
aBoard
,
aPlotter
,
layer_mask
,
plotOpt
);
else
PlotStandardLayer
(
aBoard
,
aPlotter
,
layer_mask
,
plotOpt
);
break
;
case
SILKSCREEN_N_FRONT
:
case
SILKSCREEN_N_BACK
:
if
(
plotOpt
.
GetFormat
()
==
PLOT_FORMAT_DXF
)
PlotLayerOutlines
(
aBoard
,
aPlotter
,
layer_mask
,
plotOpt
);
else
PlotSilkScreen
(
aBoard
,
aPlotter
,
layer_mask
,
plotOpt
);
// Gerber: Subtract soldermask from silkscreen if enabled
...
...
@@ -444,6 +464,115 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
itemplotter
.
PlotDrillMarks
();
}
/* Plot outlines of copper, for copper layer
*/
#include "clipper.hpp"
void
PlotLayerOutlines
(
BOARD
*
aBoard
,
PLOTTER
*
aPlotter
,
LAYER_MSK
aLayerMask
,
const
PCB_PLOT_PARAMS
&
aPlotOpt
)
{
BRDITEMS_PLOTTER
itemplotter
(
aPlotter
,
aBoard
,
aPlotOpt
);
itemplotter
.
SetLayerMask
(
aLayerMask
);
CPOLYGONS_LIST
outlines
;
for
(
LAYER_NUM
layer
=
FIRST_LAYER
;
layer
<
NB_PCB_LAYERS
;
layer
++
)
{
LAYER_MSK
layer_mask
=
GetLayerMask
(
layer
);
if
(
(
aLayerMask
&
layer_mask
)
==
0
)
continue
;
outlines
.
RemoveAllContours
();
aBoard
->
ConvertBrdLayerToPolygonalContours
(
layer
,
outlines
);
// Merge all overlapping polygons.
KI_POLYGON_SET
kpolygons
;
KI_POLYGON_SET
ktmp
;
outlines
.
ExportTo
(
ktmp
);
kpolygons
+=
ktmp
;
// Plot outlines
std
::
vector
<
wxPoint
>
cornerList
;
for
(
unsigned
ii
=
0
;
ii
<
kpolygons
.
size
();
ii
++
)
{
KI_POLYGON
polygon
=
kpolygons
[
ii
];
// polygon contains only one polygon, but it can have holes linked by
// overlapping segments.
// To plot clean outlines, we have to break this polygon into more polygons with
// no overlapping segments, using Clipper, because boost::polygon
// does not allow that
ClipperLib
::
Path
raw_polygon
;
ClipperLib
::
Paths
normalized_polygons
;
for
(
unsigned
ic
=
0
;
ic
<
polygon
.
size
();
ic
++
)
{
KI_POLY_POINT
corner
=
*
(
polygon
.
begin
()
+
ic
);
raw_polygon
.
push_back
(
ClipperLib
::
IntPoint
(
corner
.
x
(),
corner
.
y
()
)
);
}
ClipperLib
::
SimplifyPolygon
(
raw_polygon
,
normalized_polygons
);
// Now we have one or more basic polygons: plot each polygon
for
(
unsigned
ii
=
0
;
ii
<
normalized_polygons
.
size
();
ii
++
)
{
ClipperLib
::
Path
&
polygon
=
normalized_polygons
[
ii
];
cornerList
.
clear
();
for
(
unsigned
jj
=
0
;
jj
<
polygon
.
size
();
jj
++
)
cornerList
.
push_back
(
wxPoint
(
polygon
[
jj
].
X
,
polygon
[
jj
].
Y
)
);
// Ensure the polygon is closed
if
(
cornerList
[
0
]
!=
cornerList
[
cornerList
.
size
()
-
1
]
)
cornerList
.
push_back
(
cornerList
[
0
]
);
aPlotter
->
PlotPoly
(
cornerList
,
NO_FILL
);
}
}
// Plot pad holes
if
(
aPlotOpt
.
GetDrillMarksType
()
!=
PCB_PLOT_PARAMS
::
NO_DRILL_SHAPE
)
{
for
(
MODULE
*
module
=
aBoard
->
m_Modules
;
module
;
module
=
module
->
Next
()
)
{
for
(
D_PAD
*
pad
=
module
->
Pads
();
pad
;
pad
=
pad
->
Next
()
)
{
wxSize
hole
=
pad
->
GetDrillSize
();
if
(
hole
.
x
==
0
||
hole
.
y
==
0
)
continue
;
if
(
hole
.
x
==
hole
.
y
)
aPlotter
->
Circle
(
pad
->
GetPosition
(),
hole
.
x
,
NO_FILL
);
else
{
wxPoint
drl_start
,
drl_end
;
int
width
;
pad
->
GetOblongDrillGeometry
(
drl_start
,
drl_end
,
width
);
aPlotter
->
ThickSegment
(
pad
->
GetPosition
()
+
drl_start
,
pad
->
GetPosition
()
+
drl_end
,
width
,
SKETCH
);
}
}
}
}
// Plot vias holes
for
(
TRACK
*
track
=
aBoard
->
m_Track
;
track
;
track
=
track
->
Next
()
)
{
const
VIA
*
via
=
dynamic_cast
<
const
VIA
*>
(
track
);
if
(
via
&&
via
->
IsOnLayer
(
layer
)
)
// via holes can be not through holes
{
aPlotter
->
Circle
(
via
->
GetPosition
(),
via
->
GetDrillValue
(),
NO_FILL
);
}
}
}
}
/* Plot a solder mask layer.
* Solder mask layers have a minimum thickness value and cannot be drawn like standard layers,
* unless the minimum thickness is 0.
...
...
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