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
fffd3be6
Commit
fffd3be6
authored
Oct 11, 2010
by
jean-pierre charras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed some issues with arcs (Arcs are a nightmare in graphic applications).
parent
c5668298
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
151 additions
and
110 deletions
+151
-110
class_GERBER.cpp
gerbview/class_GERBER.cpp
+2
-1
class_GERBER.h
gerbview/class_GERBER.h
+1
-1
class_gerber_draw_item.cpp
gerbview/class_gerber_draw_item.cpp
+6
-0
test-polygon_with_arc-fill.gbr
gerbview/gerber_test_files/test-polygon_with_arc-fill.gbr
+18
-0
rs274d.cpp
gerbview/rs274d.cpp
+123
-107
tracepcb.cpp
gerbview/tracepcb.cpp
+1
-1
No files found.
gerbview/class_GERBER.cpp
View file @
fffd3be6
...
...
@@ -57,7 +57,7 @@
GERBER
::
GERBER
(
WinEDA_GerberFrame
*
aParent
,
int
aLayer
)
{
m_Parent
=
aParent
;
m_
Layer
=
aLayer
;
// L
ayer Number
m_
GraphicLayer
=
aLayer
;
// Graphic l
ayer Number
m_Selected_Tool
=
FIRST_DCODE
;
...
...
@@ -157,6 +157,7 @@ void GERBER::ResetDefaultValues()
m_FilesPtr
=
0
;
m_PolygonFillMode
=
false
;
m_PolygonFillModeState
=
0
;
m_Selected_Tool
=
FIRST_DCODE
;
}
...
...
gerbview/class_GERBER.h
View file @
fffd3be6
...
...
@@ -33,7 +33,7 @@ public:
wxString
m_FileName
;
// Full File Name for this layer
wxString
m_ImageName
;
// Image name, from IN <name>* command
wxString
m_LayerName
;
// Layer name, from LN <name>* command
int
m_
Layer
;
// L
ayer Number
int
m_
GraphicLayer
;
// Graphic l
ayer Number
bool
m_LayerNegative
;
// true = Negative Layer
bool
m_GerbMetric
;
// false = Inches, true = metric
bool
m_Relative
;
// false = absolute Coord, true = relative Coord
...
...
gerbview/class_gerber_draw_item.cpp
View file @
fffd3be6
...
...
@@ -352,6 +352,12 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
break
;
case
GBR_ARC
:
#if 0 // for arc debug only
GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
GetABPosition( m_ArcCentre ), 0, color );
GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_End ),
GetABPosition( m_ArcCentre ), 0, color );
#endif
if
(
!
isFilled
)
{
GRArc1
(
&
aPanel
->
m_ClipBox
,
aDC
,
GetABPosition
(
m_Start
),
...
...
gerbview/gerber_test_files/test-polygon_with_arc-fill.gbr
0 → 100644
View file @
fffd3be6
G04 Draw a rectangle with a rounded right side
G04 Hand coded by Julian Lamb *
%MOIN*%
%FSLAX23Y23*%
%ADD10C,0.050*%
G04 Draw a rectangle with a rounded right side*
G36*
G01X0Y0D02*
X00200Y0D01*
G75*
G03X00200Y00200I0J00100D01*
G01X0Y00200D01*
G04 Do not close with a final line, so let gerbv automatically close*
G37*
M02*
gerbview/rs274d.cpp
View file @
fffd3be6
...
...
@@ -3,12 +3,15 @@
/********************/
#include "fctsys.h"
//#include "polygons_defs.h"
#include "common.h"
//#include "confirm.h"
//#include "macros.h"
#include "gerbview.h"
#include "trigo.h"
#include "macros.h"
#include "class_gerber_draw_item.h"
#include "class_GERBER.h"
...
...
@@ -20,8 +23,8 @@
/* Gerber: NOTES about some important commands found in RS274D and RS274X (G codes):
* Gn =
* G01 linear interpolation (right trace)
* G02, G20, G21 Circular interpolation, meaning trig <0
* G03, G30, G31 Circular interpolation, meaning trigo> 0
* G02, G20, G21 Circular interpolation, meaning trig <0
(clockwise)
* G03, G30, G31 Circular interpolation, meaning trigo> 0
(counterclockwise)
* G04 = comment
* G06 parabolic interpolation
* G07 Cubic Interpolation
...
...
@@ -174,7 +177,7 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
aGbrItem
->
m_Size
.
x
=
aGbrItem
->
m_Size
.
y
=
aWidth
;
aGbrItem
->
m_Start
=
aStart
;
aGbrItem
->
m_End
=
aEnd
;
aGbrItem
->
m_End
=
aEnd
;
aGbrItem
->
m_DCode
=
Dcode_index
;
aGbrItem
->
m_LayerNegative
=
aLayerNegative
;
...
...
@@ -224,8 +227,8 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
*/
static
void
fillArcGBRITEM
(
GERBER_DRAW_ITEM
*
aGbrItem
,
int
Dcode_index
,
int
aLayer
,
const
wxPoint
&
aStart
,
const
wxPoint
&
aEnd
,
const
wxPoint
&
rel_c
enter
,
int
aWidth
,
bool
clockwise
,
bool
m
ultiquadrant
,
const
wxPoint
&
aRelC
enter
,
int
aWidth
,
bool
aClockwise
,
bool
aM
ultiquadrant
,
bool
aLayerNegative
,
bool
aImageNegative
)
{
...
...
@@ -236,66 +239,88 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
aGbrItem
->
m_Size
.
x
=
aGbrItem
->
m_Size
.
y
=
aWidth
;
aGbrItem
->
m_Flashed
=
false
;
if
(
multiquadrant
)
{
center
.
x
=
aStart
.
x
+
rel_center
.
x
;
center
.
y
=
aStart
.
y
+
rel_center
.
y
;
if
(
clockwise
)
{
aGbrItem
->
m_Start
=
aStart
;
aGbrItem
->
m_End
=
aEnd
;
}
else
{
aGbrItem
->
m_Start
=
aEnd
;
aGbrItem
->
m_End
=
aStart
;
}
}
if
(
aMultiquadrant
)
center
=
aStart
+
aRelCenter
;
else
{
center
=
rel_center
;
// in single quadrant mode the relative coordinate aRelCenter is always >= 0
// So we must recalculate the actual sign of aRelCenter.x and aRelCenter.y
center
=
aRelCenter
;
// calculate arc end coordinate relative to the staring point,
// because center is relative to the center point
delta
=
aEnd
-
aStart
;
// now calculate the relative to aStart center position, for a draw function
// that use trigonometric arc angle (or counter-clockwise)
/* Quadrants:
* Y
* 2 | 1
* -------X
* 3 | 4
* C = actual relative arc center, S = arc start (axis origin) E = relative arc end
*/
if
(
(
delta
.
x
>=
0
)
&&
(
delta
.
y
>=
0
)
)
{
// Quadrant 2
/* Quadrant 1 (trigo or cclockwise):
* C | E
* ---S---
* 3 | 4
*/
NEGATE
(
center
.
x
);
}
else
if
(
(
delta
.
x
>=
0
)
&&
(
delta
.
y
<
0
)
)
{
// Quadrant 1
center
.
y
=
-
center
.
y
;
/* Quadrant 4 (trigo or cclockwise):
* 2 | C
* ---S---
* 3 | E
*/
// Nothing to do
}
else
if
(
(
delta
.
x
<
0
)
&&
(
delta
.
y
>=
0
)
)
{
// Quadrant 4
center
.
x
=
-
center
.
x
;
/* Quadrant 2 (trigo or cclockwise):
* E | 1
* ---S---
* C | 4
*/
NEGATE
(
center
.
x
);
NEGATE
(
center
.
y
);
}
else
{
// Quadrant 3
center
.
x
=
-
center
.
x
;
center
.
y
=
-
center
.
y
;
/* Quadrant 3 (trigo or cclockwise):
* 2 | 1
* ---S---
* E | C
*/
NEGATE
(
center
.
y
);
}
center
.
x
+=
aStart
.
x
;
center
.
y
+=
aStart
.
y
;
// Due to your draw arc function, we need this:
if
(
!
aClockwise
)
center
=
-
center
;
if
(
clockwise
)
{
aGbrItem
->
m_Start
=
aStart
;
aGbrItem
->
m_End
=
aEnd
;
}
else
{
aGbrItem
->
m_Start
=
aEnd
;
aGbrItem
->
m_End
=
aStart
;
}
// Calculate actual arc center coordinate:
center
+=
aStart
;
}
if
(
aClockwise
)
{
aGbrItem
->
m_Start
=
aStart
;
aGbrItem
->
m_End
=
aEnd
;
}
else
{
aGbrItem
->
m_Start
=
aEnd
;
aGbrItem
->
m_End
=
aStart
;
}
aGbrItem
->
m_DCode
=
Dcode_index
;
aGbrItem
->
m_ArcCentre
=
center
;
aGbrItem
->
m_DCode
=
Dcode_index
;
aGbrItem
->
m_LayerNegative
=
aLayerNegative
;
aGbrItem
->
m_ImageNegative
=
aImageNegative
;
...
...
@@ -370,68 +395,51 @@ static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGbrItem,
aStart
,
aEnd
,
rel_center
,
0
,
clockwise
,
multiquadrant
,
aLayerNegative
,
aImageNegative
);
// dummyTrack has right geometric parameters, and has its Y coordinates negated (to match the pcbnew Y axis).
// Approximate arc by 36 segments per 360 degree
const
int
increment_angle
=
360
/
36
;
wxPoint
center
;
center
=
dummyGbrItem
.
m_ArcCentre
;
// Calculate
relative coordinates
;
// Calculate
coordinates relative to arc center
;
wxPoint
start
=
dummyGbrItem
.
m_Start
-
center
;
wxPoint
end
=
dummyGbrItem
.
m_End
-
center
;
/* Calculate angle arc
* angle is here clockwise because Y axis is reversed
* angles are in 0.1 deg
* angle is trigonometrical (counter-clockwise),
* and axis is the X,Y gerber coordinates
*/
double
start_angle
=
atan2
(
(
double
)
start
.
y
,
(
double
)
start
.
x
);
start_angle
=
180
*
start_angle
/
M_PI
;
double
end_angle
=
atan2
(
(
double
)
end
.
y
,
(
double
)
end
.
x
);
end_angle
=
180
*
end_angle
/
M_PI
;
double
angle
=
start_angle
-
end_angle
;
// D( printf( " >>>> st %d,%d angle %f, end %d,%d angle %f delta %f\n",
// start.x, start.y, start_angle, end.x, end.y, end_angle, angle ) );
if
(
!
clockwise
)
{
EXCHG
(
start
,
end
);
D
(
printf
(
" >>>> reverse arc
\n
"
)
);
}
// Normalize angle
while
(
angle
>
360.0
)
angle
-=
360.0
;
while
(
angle
<
0.0
)
angle
+=
360.0
;
int
count
=
(
int
)
(
angle
/
increment_angle
);
if
(
count
<=
0
)
count
=
1
;
// D( printf( " >>>> angle %f, cnt %d sens %d\n", angle, count, clockwise ) );
int
start_angle
=
wxRound
(
atan2
(
(
double
)
start
.
y
,
(
double
)
start
.
x
)
*
1800
/
M_PI
);
int
end_angle
=
wxRound
(
atan2
(
(
double
)
end
.
y
,
(
double
)
end
.
x
)
*
1800
/
M_PI
);
// dummyTrack has right geometric parameters, but
// fillArcGBRITEM calculate arc parameters for a draw function that expects
// start_angle < end_angle. So ensure this is the case here:
// Due to the fact atan2 returns angles between -180 to + 180 degrees,
// this not always the case ( a modulo 360.0 degrees can be lost )
if
(
start_angle
>
end_angle
)
end_angle
+=
3600
;
int
arc_angle
=
start_angle
-
end_angle
;
// Approximate arc by 36 segments per 360 degree
int
increment_angle
=
3600
/
36
;
int
count
=
ABS
(
arc_angle
/
increment_angle
);
// calculate segments
// calculate polygon corners
// when not clockwise, dummyGbrItem arc goes from end to start
wxPoint
start_arc
=
start
;
for
(
int
ii
=
1
;
ii
<=
count
;
ii
++
)
for
(
int
ii
=
0
;
ii
<=
count
;
ii
++
)
{
int
rot
;
wxPoint
end_arc
=
start
;
int
rot
=
10
*
ii
*
increment_angle
;
// rot is in 0.1 deg
if
(
ii
<
count
)
{
if
(
clockwise
)
RotatePoint
(
&
end_arc
,
rot
);
else
RotatePoint
(
&
end_arc
,
-
rot
);
}
if
(
clockwise
)
rot
=
ii
*
increment_angle
;
// rot is in 0.1 deg
else
end_arc
=
end
;
rot
=
(
count
-
ii
)
*
increment_angle
;
// rot is in 0.1 deg
// D( printf( " >> Add arc %d rot %d, edge poly item %d,%d to %d,%d\n",
// ii, rot, start_arc.x, start_arc.y,end_arc.x, end_arc.y ); )
if
(
ii
<
count
)
RotatePoint
(
&
end_arc
,
-
rot
);
else
// last point
end_arc
=
clockwise
?
end
:
start
;
if
(
aGbrItem
->
m_PolyCorners
.
size
()
==
0
)
aGbrItem
->
m_PolyCorners
.
push_back
(
start_arc
+
center
);
aGbrItem
->
m_PolyCorners
.
push_back
(
end_arc
+
center
);
start_arc
=
end_arc
;
...
...
@@ -466,17 +474,18 @@ wxPoint GERBER::ReadXYCoord( char*& Text )
{
type_coord
=
*
Text
;
Text
++
;
text
=
line
;
text
=
line
;
nbdigits
=
0
;
while
(
IsNumber
(
*
Text
)
)
{
if
(
*
Text
==
'.'
)
is_float
=
true
;
// count digits only (sign and decimal point are not counted)
if
(
(
*
Text
>=
'0'
)
&&
(
*
Text
<=
'9'
)
)
nbdigits
++
;
*
(
text
++
)
=
*
(
Text
++
);
}
}
*
text
=
0
;
if
(
is_float
)
...
...
@@ -502,7 +511,7 @@ wxPoint GERBER::ReadXYCoord( char*& Text )
*
text
=
0
;
}
current_coord
=
atoi
(
line
);
double
real_scale
=
1.0
;
double
real_scale
=
1.0
;
double
scale_list
[
10
]
=
{
10000.0
,
1000.0
,
100.0
,
10.0
,
...
...
@@ -562,12 +571,13 @@ wxPoint GERBER::ReadIJCoord( char*& Text )
{
type_coord
=
*
Text
;
Text
++
;
text
=
line
;
text
=
line
;
nbdigits
=
0
;
while
(
IsNumber
(
*
Text
)
)
{
if
(
*
Text
==
'.'
)
is_float
=
true
;
// count digits only (sign and decimal point are not counted)
if
(
(
*
Text
>=
'0'
)
&&
(
*
Text
<=
'9'
)
)
nbdigits
++
;
...
...
@@ -736,8 +746,8 @@ bool GERBER::Execute_G_Command( char*& text, int G_commande )
break
;
case
GC_TURN_OFF_360_INTERPOL
:
// disable Multi cadran arc and Arc interpol
m_360Arc_enbl
=
false
;
m_Iterpolation
=
GERB_INTERPOL_LINEAR_1X
;
m_360Arc_enbl
=
false
;
m_Iterpolation
=
GERB_INTERPOL_LINEAR_1X
;
// not sure it should be done
break
;
case
GC_TURN_ON_360_INTERPOL
:
...
...
@@ -857,7 +867,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
pcb
->
m_Drawings
.
Append
(
gbritem
);
gbritem
->
m_Shape
=
GBR_POLYGON
;
gbritem
->
SetLayer
(
activeLayer
);
gbritem
->
m_Flashed
=
false
;
gbritem
->
m_Flashed
=
false
;
}
switch
(
m_Iterpolation
)
...
...
@@ -865,18 +875,20 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
case
GERB_INTERPOL_ARC_NEG
:
case
GERB_INTERPOL_ARC_POS
:
gbritem
=
(
GERBER_DRAW_ITEM
*
)(
pcb
->
m_Drawings
.
GetLast
()
);
// D( printf( "Add arc poly %d,%d to %d,%d fill %d interpol %d 360_enb %d\n",
// m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x,
// m_CurrentPos.y, m_PolygonFillModeState,
// D( printf( "Add arc poly %d,%d to %d,%d fill %d interpol %d 360_enb %d\n",
// m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x,
// m_CurrentPos.y, m_PolygonFillModeState,
// m_Iterpolation, m_360Arc_enbl ); )
fillArcPOLY
(
pcb
,
gbritem
,
m_PreviousPos
,
m_CurrentPos
,
m_IJPos
,
(
m_Iterpolation
==
GERB_INTERPOL_ARC_NEG
)
?
false
:
true
,
m_360Arc_enbl
,
m_LayerNegative
,
m_ImageNegative
);
m_CurrentPos
,
m_IJPos
,
(
m_Iterpolation
==
GERB_INTERPOL_ARC_NEG
)
?
false
:
true
,
m_360Arc_enbl
,
m_LayerNegative
,
m_ImageNegative
);
break
;
default
:
gbritem
=
(
GERBER_DRAW_ITEM
*
)(
pcb
->
m_Drawings
.
GetLast
()
);
// D( printf( "Add poly edge %d,%d to %d,%d fill %d\n",
// m_PreviousPos.x, m_PreviousPos.y,
// m_CurrentPos.x, m_CurrentPos.y, m_Iterpolation ); )
...
...
@@ -931,11 +943,12 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
case
GERB_INTERPOL_LINEAR_1X
:
gbritem
=
new
GERBER_DRAW_ITEM
(
pcb
,
this
);
pcb
->
m_Drawings
.
Append
(
gbritem
);
// D( printf( "Add line %d,%d to %d,%d\n",
// m_PreviousPos.x, m_PreviousPos.y,
// m_CurrentPos.x, m_CurrentPos.y ); )
fillLineGBRITEM
(
gbritem
,
dcode
,
activeLayer
,
m_PreviousPos
,
m_CurrentPos
,
size
.
x
,
m_LayerNegative
,
m_ImageNegative
);
m_CurrentPos
,
size
.
x
,
m_LayerNegative
,
m_ImageNegative
);
break
;
case
GERB_INTERPOL_LINEAR_01X
:
...
...
@@ -948,14 +961,15 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
case
GERB_INTERPOL_ARC_POS
:
gbritem
=
new
GERBER_DRAW_ITEM
(
pcb
,
this
);
pcb
->
m_Drawings
.
Append
(
gbritem
);
// D( printf( "Add arc %d,%d to %d,%d center %d, %d interpol %d 360_enb %d\n",
// m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x,
// m_CurrentPos.y, m_IJPos.x,
// m_IJPos.y, m_Iterpolation, m_360Arc_enbl ); )
fillArcGBRITEM
(
gbritem
,
dcode
,
activeLayer
,
m_PreviousPos
,
m_CurrentPos
,
m_IJPos
,
size
.
x
,
(
m_Iterpolation
==
GERB_INTERPOL_ARC_NEG
)
?
false
:
true
,
m_360Arc_enbl
,
m_CurrentPos
,
m_IJPos
,
size
.
x
,
(
m_Iterpolation
==
GERB_INTERPOL_ARC_NEG
)
?
false
:
true
,
m_360Arc_enbl
,
m_LayerNegative
,
m_ImageNegative
);
break
;
...
...
@@ -970,7 +984,8 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
break
;
case
2
:
// code D2: exposure OFF (i.e. "move to")
m_Exposure
=
false
;
m_Exposure
=
false
;
// D( printf( "Move to %d,%d to %d,%d\n",
// m_PreviousPos.x, m_PreviousPos.y,
// m_CurrentPos.x, m_CurrentPos.y ); )
...
...
@@ -988,6 +1003,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
gbritem
=
new
GERBER_DRAW_ITEM
(
pcb
,
this
);
pcb
->
m_Drawings
.
Append
(
gbritem
);
// D( printf( "Add flashed dcode %d layer %d at %d %d\n", dcode, activeLayer,
// m_CurrentPos.x, m_CurrentPos.y ); )
fillFlashedGBRITEM
(
gbritem
,
aperture
,
...
...
gerbview/tracepcb.cpp
View file @
fffd3be6
...
...
@@ -159,7 +159,7 @@ void Show_Items_DCode_Value( WinEDA_DrawPanel* aPanel, wxDC* aDC, BOARD* aPcb, i
if
(
gerb_item
->
m_DCode
<=
0
)
continue
;
if
(
gerb_item
->
m_Flashed
)
if
(
gerb_item
->
m_Flashed
||
gerb_item
->
m_Shape
==
GBR_ARC
)
pos
=
gerb_item
->
m_Start
;
else
{
...
...
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