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
22045b61
Commit
22045b61
authored
Oct 14, 2013
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Converted tabs to spaces. Removed trailing whitespaces.
parent
ac489ece
Changes
55
Hide whitespace changes
Inline
Side-by-side
Showing
55 changed files
with
3023 additions
and
3024 deletions
+3023
-3024
drawpanel_gal.cpp
common/drawpanel_gal.cpp
+20
-20
color4d.cpp
common/gal/color4d.cpp
+2
-3
opengl_gal.cpp
common/gal/opengl/opengl_gal.cpp
+1
-1
shader.frag
common/gal/opengl/shader.frag
+1
-1
shader.vert
common/gal/opengl/shader.vert
+8
-8
seg.cpp
common/geometry/seg.cpp
+60
-60
shape_collisions.cpp
common/geometry/shape_collisions.cpp
+155
-155
shape_line_chain.cpp
common/geometry/shape_line_chain.cpp
+362
-362
fcontext.s
common/system/fcontext.s
+3
-3
make_i386_pe_gas.S
common/system/make_i386_pe_gas.S
+33
-33
context_menu.cpp
common/tool/context_menu.cpp
+21
-21
tool_base.cpp
common/tool/tool_base.cpp
+5
-5
tool_dispatcher.cpp
common/tool/tool_dispatcher.cpp
+168
-168
tool_event.cpp
common/tool/tool_event.cpp
+89
-89
tool_interactive.cpp
common/tool/tool_interactive.cpp
+8
-8
tool_manager.cpp
common/tool/tool_manager.cpp
+165
-165
class_drawpanel_gal.h
include/class_drawpanel_gal.h
+1
-1
color4d.h
include/gal/color4d.h
+1
-1
shader.h
include/gal/opengl/shader.h
+5
-5
seg.h
include/geometry/seg.h
+266
-266
shape.h
include/geometry/shape.h
+97
-97
shape_circle.h
include/geometry/shape_circle.h
+34
-34
shape_index.h
include/geometry/shape_index.h
+4
-4
shape_index_list.h
include/geometry/shape_index_list.h
+218
-218
shape_line_chain.h
include/geometry/shape_line_chain.h
+494
-494
shape_rect.h
include/geometry/shape_rect.h
+109
-109
box2.h
include/math/box2.h
+2
-2
vector2d.h
include/math/vector2d.h
+1
-1
context_menu.h
include/tool/context_menu.h
+94
-94
coroutine.h
include/tool/coroutine.h
+152
-152
delegate.h
include/tool/delegate.h
+54
-54
coroutine_example.cpp
include/tool/examples/coroutine_example.cpp
+31
-31
delegate_example.cpp
include/tool/examples/delegate_example.cpp
+18
-18
tool_base.h
include/tool/tool_base.h
+117
-117
tool_dispatcher.h
include/tool/tool_dispatcher.h
+3
-3
tool_event.h
include/tool/tool_event.h
+54
-54
tool_interactive.h
include/tool/tool_interactive.h
+67
-67
view_controls.h
include/view/view_controls.h
+1
-1
edit.cpp
pcbnew/edit.cpp
+0
-0
pcb_painter.cpp
pcbnew/pcb_painter.cpp
+1
-1
pns_itemset.h
pcbnew/router/pns_itemset.h
+1
-1
pns_joint.h
pcbnew/router/pns_joint.h
+11
-11
pns_line.cpp
pcbnew/router/pns_line.cpp
+5
-5
pns_line.h
pcbnew/router/pns_line.h
+10
-10
pns_line_placer.cpp
pcbnew/router/pns_line_placer.cpp
+10
-10
pns_line_placer.h
pcbnew/router/pns_line_placer.h
+24
-24
pns_node.cpp
pcbnew/router/pns_node.cpp
+11
-11
pns_node.h
pcbnew/router/pns_node.h
+12
-12
pns_optimizer.cpp
pcbnew/router/pns_optimizer.cpp
+8
-8
pns_router.cpp
pcbnew/router/pns_router.cpp
+1
-1
pns_shove.cpp
pcbnew/router/pns_shove.cpp
+1
-1
pns_shove.h
pcbnew/router/pns_shove.h
+1
-1
pns_walkaround.cpp
pcbnew/router/pns_walkaround.cpp
+1
-1
pns_walkaround.h
pcbnew/router/pns_walkaround.h
+1
-1
router_tool.cpp
pcbnew/router/router_tool.cpp
+1
-1
No files found.
common/drawpanel_gal.cpp
View file @
22045b61
...
@@ -78,21 +78,21 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
...
@@ -78,21 +78,21 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
Connect
(
wxEVT_SIZE
,
wxSizeEventHandler
(
EDA_DRAW_PANEL_GAL
::
onSize
),
NULL
,
this
);
Connect
(
wxEVT_SIZE
,
wxSizeEventHandler
(
EDA_DRAW_PANEL_GAL
::
onSize
),
NULL
,
this
);
/* Generic events for the Tool Dispatcher */
/* Generic events for the Tool Dispatcher */
Connect
(
wxEVT_MOTION
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_MOTION
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_LEFT_UP
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_LEFT_UP
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_LEFT_DOWN
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_LEFT_DOWN
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_RIGHT_UP
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_RIGHT_UP
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_RIGHT_DOWN
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_RIGHT_DOWN
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_MIDDLE_UP
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_MIDDLE_UP
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_MIDDLE_DOWN
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_MIDDLE_DOWN
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_MOUSEWHEEL
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_MOUSEWHEEL
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_CHAR_HOOK
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
skipEvent
)
);
Connect
(
wxEVT_CHAR_HOOK
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
skipEvent
)
);
Connect
(
wxEVT_KEY_UP
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_KEY_UP
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_KEY_DOWN
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_KEY_DOWN
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
Connect
(
wxEVT_ENTER_WINDOW
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEnter
),
NULL
,
this
);
Connect
(
wxEVT_ENTER_WINDOW
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEnter
),
NULL
,
this
);
Connect
(
KiGfx
::
WX_VIEW_CONTROLS
::
EVT_REFRESH_MOUSE
,
Connect
(
KiGfx
::
WX_VIEW_CONTROLS
::
EVT_REFRESH_MOUSE
,
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
wxEventHandler
(
EDA_DRAW_PANEL_GAL
::
onEvent
),
NULL
,
this
);
m_refreshTimer
.
SetOwner
(
this
);
m_refreshTimer
.
SetOwner
(
this
);
Connect
(
wxEVT_TIMER
,
wxTimerEventHandler
(
EDA_DRAW_PANEL_GAL
::
onRefreshTimer
),
NULL
,
this
);
Connect
(
wxEVT_TIMER
,
wxTimerEventHandler
(
EDA_DRAW_PANEL_GAL
::
onRefreshTimer
),
NULL
,
this
);
...
@@ -171,7 +171,7 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool eraseBackground, const wxRect* rect )
...
@@ -171,7 +171,7 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool eraseBackground, const wxRect* rect )
m_refreshTimer
.
Start
(
(
MinRefreshPeriod
-
delta
).
ToLong
(),
true
);
m_refreshTimer
.
Start
(
(
MinRefreshPeriod
-
delta
).
ToLong
(),
true
);
m_pendingRefresh
=
true
;
m_pendingRefresh
=
true
;
}
}
}
}
void
EDA_DRAW_PANEL_GAL
::
SwitchBackend
(
GalType
aGalType
)
void
EDA_DRAW_PANEL_GAL
::
SwitchBackend
(
GalType
aGalType
)
...
@@ -223,13 +223,13 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType )
...
@@ -223,13 +223,13 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType )
void
EDA_DRAW_PANEL_GAL
::
onEvent
(
wxEvent
&
aEvent
)
void
EDA_DRAW_PANEL_GAL
::
onEvent
(
wxEvent
&
aEvent
)
{
{
if
(
!
m_eventDispatcher
)
if
(
!
m_eventDispatcher
)
{
{
aEvent
.
Skip
();
aEvent
.
Skip
();
return
;
return
;
}
}
else
else
{
{
m_eventDispatcher
->
DispatchWxEvent
(
aEvent
);
m_eventDispatcher
->
DispatchWxEvent
(
aEvent
);
}
}
...
...
common/gal/color4d.cpp
View file @
22045b61
...
@@ -159,7 +159,6 @@ void COLOR4D::FromHSV( double aInH, double aInS, double aInV )
...
@@ -159,7 +159,6 @@ void COLOR4D::FromHSV( double aInH, double aInS, double aInV )
b
=
q
;
b
=
q
;
break
;
break
;
}
}
}
}
...
@@ -168,7 +167,7 @@ COLOR4D& COLOR4D::Saturate( double aFactor )
...
@@ -168,7 +167,7 @@ COLOR4D& COLOR4D::Saturate( double aFactor )
double
h
,
s
,
v
;
double
h
,
s
,
v
;
ToHSV
(
h
,
s
,
v
);
ToHSV
(
h
,
s
,
v
);
FromHSV
(
h
,
aFactor
,
1.0
);
FromHSV
(
h
,
aFactor
,
1.0
);
return
*
this
;
return
*
this
;
}
}
common/gal/opengl/opengl_gal.cpp
View file @
22045b61
...
@@ -127,7 +127,7 @@ void OPENGL_GAL::BeginDrawing()
...
@@ -127,7 +127,7 @@ void OPENGL_GAL::BeginDrawing()
glViewport
(
0
,
0
,
(
GLsizei
)
screenSize
.
x
,
(
GLsizei
)
screenSize
.
y
);
glViewport
(
0
,
0
,
(
GLsizei
)
screenSize
.
x
,
(
GLsizei
)
screenSize
.
y
);
// Create the screen transformation
// Create the screen transformation
glOrtho
(
0
,
(
GLint
)
screenSize
.
x
,
0
,
(
GLsizei
)
screenSize
.
y
,
glOrtho
(
0
,
(
GLint
)
screenSize
.
x
,
0
,
(
GLsizei
)
screenSize
.
y
,
-
depthRange
.
x
,
-
depthRange
.
y
);
-
depthRange
.
x
,
-
depthRange
.
y
);
// Prepare rendering target buffers
// Prepare rendering target buffers
...
...
common/gal/opengl/shader.frag
View file @
22045b61
...
@@ -49,7 +49,7 @@ void strokedCircle( vec2 aCoord, float aRadius, float aWidth )
...
@@ -49,7 +49,7 @@ void strokedCircle( vec2 aCoord, float aRadius, float aWidth )
float
innerRadius
=
aRadius
-
(
aWidth
/
2
);
float
innerRadius
=
aRadius
-
(
aWidth
/
2
);
float
relWidth
=
innerRadius
/
outerRadius
;
float
relWidth
=
innerRadius
/
outerRadius
;
if
(
(
dot
(
aCoord
,
aCoord
)
<
1
.
0
f
)
&&
if
(
(
dot
(
aCoord
,
aCoord
)
<
1
.
0
f
)
&&
(
dot
(
aCoord
,
aCoord
)
>
relWidth
*
relWidth
)
)
(
dot
(
aCoord
,
aCoord
)
>
relWidth
*
relWidth
)
)
gl_FragColor
=
gl_Color
;
gl_FragColor
=
gl_Color
;
else
else
...
...
common/gal/opengl/shader.vert
View file @
22045b61
...
@@ -42,23 +42,23 @@ void main()
...
@@ -42,23 +42,23 @@ void main()
{
{
// Pass attributes to the fragment shader
// Pass attributes to the fragment shader
shaderParams
=
attrShaderParams
;
shaderParams
=
attrShaderParams
;
if
(
shaderParams
[
0
]
==
SHADER_LINE
)
if
(
shaderParams
[
0
]
==
SHADER_LINE
)
{
{
float
lineWidth
=
shaderParams
[
3
];
float
lineWidth
=
shaderParams
[
3
];
float
worldScale
=
gl_ModelViewMatrix
[
0
][
0
];
float
worldScale
=
gl_ModelViewMatrix
[
0
][
0
];
float
scale
;
float
scale
;
// Make lines appear to be at least 1 pixel wide
// Make lines appear to be at least 1 pixel wide
if
(
worldScale
*
lineWidth
<
MIN_WIDTH
)
if
(
worldScale
*
lineWidth
<
MIN_WIDTH
)
scale
=
MIN_WIDTH
/
(
worldScale
*
lineWidth
);
scale
=
MIN_WIDTH
/
(
worldScale
*
lineWidth
);
else
else
scale
=
1
.
0
f
;
scale
=
1
.
0
f
;
gl_Position
=
gl_ModelViewProjectionMatrix
*
gl_Position
=
gl_ModelViewProjectionMatrix
*
(
gl_Vertex
+
vec4
(
shaderParams
.
yz
*
scale
,
0
.
0
,
0
.
0
)
);
(
gl_Vertex
+
vec4
(
shaderParams
.
yz
*
scale
,
0
.
0
,
0
.
0
)
);
}
}
else
if
(
(
shaderParams
[
0
]
==
SHADER_STROKED_CIRCLE
)
||
else
if
(
(
shaderParams
[
0
]
==
SHADER_STROKED_CIRCLE
)
||
(
shaderParams
[
0
]
==
SHADER_FILLED_CIRCLE
)
)
(
shaderParams
[
0
]
==
SHADER_FILLED_CIRCLE
)
)
{
{
// Compute relative circle coordinates basing on indices
// Compute relative circle coordinates basing on indices
...
@@ -69,7 +69,7 @@ void main()
...
@@ -69,7 +69,7 @@ void main()
circleCoords
=
vec2
(
sqrt
(
3
.
0
f
),
-
1
.
0
f
);
circleCoords
=
vec2
(
sqrt
(
3
.
0
f
),
-
1
.
0
f
);
else
if
(
shaderParams
[
1
]
==
3
.
0
f
)
else
if
(
shaderParams
[
1
]
==
3
.
0
f
)
circleCoords
=
vec2
(
0
.
0
f
,
2
.
0
f
);
circleCoords
=
vec2
(
0
.
0
f
,
2
.
0
f
);
// Semicircle
// Semicircle
else
if
(
shaderParams
[
1
]
==
4
.
0
f
)
else
if
(
shaderParams
[
1
]
==
4
.
0
f
)
circleCoords
=
vec2
(
-
3
.
0
f
/
sqrt
(
3
.
0
f
),
0
.
0
f
);
circleCoords
=
vec2
(
-
3
.
0
f
/
sqrt
(
3
.
0
f
),
0
.
0
f
);
...
@@ -81,7 +81,7 @@ void main()
...
@@ -81,7 +81,7 @@ void main()
// Make the line appear to be at least 1 pixel wide
// Make the line appear to be at least 1 pixel wide
float
lineWidth
=
shaderParams
[
3
];
float
lineWidth
=
shaderParams
[
3
];
float
worldScale
=
gl_ModelViewMatrix
[
0
][
0
];
float
worldScale
=
gl_ModelViewMatrix
[
0
][
0
];
// Make lines appear to be at least 1 pixel width
// Make lines appear to be at least 1 pixel width
if
(
worldScale
*
lineWidth
<
MIN_WIDTH
)
if
(
worldScale
*
lineWidth
<
MIN_WIDTH
)
shaderParams
[
3
]
=
shaderParams
[
3
]
/
(
worldScale
*
lineWidth
);
shaderParams
[
3
]
=
shaderParams
[
3
]
/
(
worldScale
*
lineWidth
);
...
@@ -93,7 +93,7 @@ void main()
...
@@ -93,7 +93,7 @@ void main()
// Pass through the coordinates like in the fixed pipeline
// Pass through the coordinates like in the fixed pipeline
gl_Position
=
ftransform
();
gl_Position
=
ftransform
();
}
}
gl_FrontColor
=
gl_Color
;
gl_FrontColor
=
gl_Color
;
}
}
common/geometry/seg.cpp
View file @
22045b61
...
@@ -32,38 +32,38 @@ template<typename T> int sgn( T val ) {
...
@@ -32,38 +32,38 @@ template<typename T> int sgn( T val ) {
bool
SEG
::
PointCloserThan
(
const
VECTOR2I
&
aP
,
int
dist
)
const
bool
SEG
::
PointCloserThan
(
const
VECTOR2I
&
aP
,
int
dist
)
const
{
{
VECTOR2I
d
=
b
-
a
;
VECTOR2I
d
=
b
-
a
;
ecoord
dist_sq
=
(
ecoord
)
dist
*
dist
;
ecoord
dist_sq
=
(
ecoord
)
dist
*
dist
;
SEG
::
ecoord
l_squared
=
d
.
Dot
(
d
);
SEG
::
ecoord
l_squared
=
d
.
Dot
(
d
);
SEG
::
ecoord
t
=
d
.
Dot
(
aP
-
a
);
SEG
::
ecoord
t
=
d
.
Dot
(
aP
-
a
);
if
(
t
<=
0
||
!
l_squared
)
if
(
t
<=
0
||
!
l_squared
)
return
(
aP
-
a
).
SquaredEuclideanNorm
()
<
dist_sq
;
return
(
aP
-
a
).
SquaredEuclideanNorm
()
<
dist_sq
;
else
if
(
t
>=
l_squared
)
else
if
(
t
>=
l_squared
)
return
(
aP
-
b
).
SquaredEuclideanNorm
()
<
dist_sq
;
return
(
aP
-
b
).
SquaredEuclideanNorm
()
<
dist_sq
;
int
dxdy
=
abs
(
d
.
x
)
-
abs
(
d
.
y
);
int
dxdy
=
abs
(
d
.
x
)
-
abs
(
d
.
y
);
if
(
(
dxdy
>=
-
1
&&
dxdy
<=
1
)
||
abs
(
d
.
x
)
<=
1
||
abs
(
d
.
y
)
<=
1
)
if
(
(
dxdy
>=
-
1
&&
dxdy
<=
1
)
||
abs
(
d
.
x
)
<=
1
||
abs
(
d
.
y
)
<=
1
)
{
{
int
ca
=
-
sgn
(
d
.
y
);
int
ca
=
-
sgn
(
d
.
y
);
int
cb
=
sgn
(
d
.
x
);
int
cb
=
sgn
(
d
.
x
);
int
cc
=
-
ca
*
a
.
x
-
cb
*
a
.
y
;
int
cc
=
-
ca
*
a
.
x
-
cb
*
a
.
y
;
ecoord
num
=
ca
*
aP
.
x
+
cb
*
aP
.
y
+
cc
;
ecoord
num
=
ca
*
aP
.
x
+
cb
*
aP
.
y
+
cc
;
num
*=
num
;
num
*=
num
;
if
(
ca
&&
cb
)
if
(
ca
&&
cb
)
num
>>=
1
;
num
>>=
1
;
if
(
num
>
(
dist_sq
+
100
)
)
if
(
num
>
(
dist_sq
+
100
)
)
return
false
;
return
false
;
else
if
(
num
<
(
dist_sq
-
100
)
)
else
if
(
num
<
(
dist_sq
-
100
)
)
return
true
;
return
true
;
}
}
VECTOR2I
nearest
;
VECTOR2I
nearest
;
nearest
.
x
=
a
.
x
+
rescale
(
t
,
(
ecoord
)
d
.
x
,
l_squared
);
nearest
.
x
=
a
.
x
+
rescale
(
t
,
(
ecoord
)
d
.
x
,
l_squared
);
nearest
.
y
=
a
.
y
+
rescale
(
t
,
(
ecoord
)
d
.
y
,
l_squared
);
nearest
.
y
=
a
.
y
+
rescale
(
t
,
(
ecoord
)
d
.
y
,
l_squared
);
...
@@ -71,7 +71,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int dist ) const
...
@@ -71,7 +71,7 @@ bool SEG::PointCloserThan( const VECTOR2I& aP, int dist ) const
}
}
SEG
::
ecoord
SEG
::
SquaredDistance
(
const
SEG
&
aSeg
)
const
SEG
::
ecoord
SEG
::
SquaredDistance
(
const
SEG
&
aSeg
)
const
{
{
// fixme: rather inefficient....
// fixme: rather inefficient....
if
(
Intersect
(
aSeg
)
)
if
(
Intersect
(
aSeg
)
)
...
@@ -91,62 +91,62 @@ SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const
...
@@ -91,62 +91,62 @@ SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const
return
m
;
return
m
;
}
}
OPT_VECTOR2I
SEG
::
Intersect
(
const
SEG
&
aSeg
,
bool
aIgnoreEndpoints
,
bool
aLines
)
const
OPT_VECTOR2I
SEG
::
Intersect
(
const
SEG
&
aSeg
,
bool
aIgnoreEndpoints
,
bool
aLines
)
const
{
{
const
VECTOR2I
e
(
b
-
a
);
const
VECTOR2I
e
(
b
-
a
);
const
VECTOR2I
f
(
aSeg
.
b
-
aSeg
.
a
);
const
VECTOR2I
f
(
aSeg
.
b
-
aSeg
.
a
);
const
VECTOR2I
ac
(
aSeg
.
a
-
a
);
const
VECTOR2I
ac
(
aSeg
.
a
-
a
);
ecoord
d
=
f
.
Cross
(
e
);
ecoord
d
=
f
.
Cross
(
e
);
ecoord
p
=
f
.
Cross
(
ac
);
ecoord
p
=
f
.
Cross
(
ac
);
ecoord
q
=
e
.
Cross
(
ac
);
ecoord
q
=
e
.
Cross
(
ac
);
if
(
d
==
0
)
if
(
d
==
0
)
return
OPT_VECTOR2I
();
return
OPT_VECTOR2I
();
if
(
!
aLines
&&
d
>
0
&&
(
q
<
0
||
q
>
d
||
p
<
0
||
p
>
d
)
)
if
(
!
aLines
&&
d
>
0
&&
(
q
<
0
||
q
>
d
||
p
<
0
||
p
>
d
)
)
return
OPT_VECTOR2I
();
return
OPT_VECTOR2I
();
if
(
!
aLines
&&
d
<
0
&&
(
q
<
d
||
p
<
d
||
p
>
0
||
q
>
0
)
)
if
(
!
aLines
&&
d
<
0
&&
(
q
<
d
||
p
<
d
||
p
>
0
||
q
>
0
)
)
return
OPT_VECTOR2I
();
return
OPT_VECTOR2I
();
if
(
!
aLines
&&
aIgnoreEndpoints
&&
(
q
==
0
||
q
==
d
)
&&
(
p
==
0
||
p
==
d
)
)
if
(
!
aLines
&&
aIgnoreEndpoints
&&
(
q
==
0
||
q
==
d
)
&&
(
p
==
0
||
p
==
d
)
)
return
OPT_VECTOR2I
();
return
OPT_VECTOR2I
();
VECTOR2I
ip
(
aSeg
.
a
.
x
+
rescale
(
q
,
(
ecoord
)
f
.
x
,
d
),
VECTOR2I
ip
(
aSeg
.
a
.
x
+
rescale
(
q
,
(
ecoord
)
f
.
x
,
d
),
aSeg
.
a
.
y
+
rescale
(
q
,
(
ecoord
)
f
.
y
,
d
)
);
aSeg
.
a
.
y
+
rescale
(
q
,
(
ecoord
)
f
.
y
,
d
)
);
return
ip
;
return
ip
;
}
}
bool
SEG
::
ccw
(
const
VECTOR2I
&
a
,
const
VECTOR2I
&
b
,
const
VECTOR2I
&
c
)
const
bool
SEG
::
ccw
(
const
VECTOR2I
&
a
,
const
VECTOR2I
&
b
,
const
VECTOR2I
&
c
)
const
{
{
return
(
ecoord
)(
c
.
y
-
a
.
y
)
*
(
b
.
x
-
a
.
x
)
>
(
ecoord
)(
b
.
y
-
a
.
y
)
*
(
c
.
x
-
a
.
x
);
return
(
ecoord
)(
c
.
y
-
a
.
y
)
*
(
b
.
x
-
a
.
x
)
>
(
ecoord
)(
b
.
y
-
a
.
y
)
*
(
c
.
x
-
a
.
x
);
}
}
bool
SEG
::
Collide
(
const
SEG
&
aSeg
,
int
aClearance
)
const
bool
SEG
::
Collide
(
const
SEG
&
aSeg
,
int
aClearance
)
const
{
{
// check for intersection
// check for intersection
// fixme: move to a method
// fixme: move to a method
if
(
ccw
(
a
,
aSeg
.
a
,
aSeg
.
b
)
!=
ccw
(
b
,
aSeg
.
a
,
aSeg
.
b
)
&&
if
(
ccw
(
a
,
aSeg
.
a
,
aSeg
.
b
)
!=
ccw
(
b
,
aSeg
.
a
,
aSeg
.
b
)
&&
ccw
(
a
,
b
,
aSeg
.
a
)
!=
ccw
(
a
,
b
,
aSeg
.
b
)
)
ccw
(
a
,
b
,
aSeg
.
a
)
!=
ccw
(
a
,
b
,
aSeg
.
b
)
)
return
true
;
return
true
;
#define CHK(_seg, _pt) \
#define CHK(_seg, _pt) \
if( (_seg).PointCloserThan (_pt, aClearance ) ) return true;
if( (_seg).PointCloserThan (_pt, aClearance ) ) return true;
CHK
(
*
this
,
aSeg
.
a
);
CHK
(
*
this
,
aSeg
.
a
);
CHK
(
*
this
,
aSeg
.
b
);
CHK
(
*
this
,
aSeg
.
b
);
CHK
(
aSeg
,
a
);
CHK
(
aSeg
,
a
);
CHK
(
aSeg
,
b
);
CHK
(
aSeg
,
b
);
#undef CHK
#undef CHK
return
false
;
return
false
;
}
}
bool
SEG
::
Contains
(
const
VECTOR2I
&
aP
)
const
bool
SEG
::
Contains
(
const
VECTOR2I
&
aP
)
const
{
{
return
PointCloserThan
(
aP
,
1
);
return
PointCloserThan
(
aP
,
1
);
}
}
common/geometry/shape_collisions.cpp
View file @
22045b61
...
@@ -34,200 +34,200 @@ typedef VECTOR2I::extended_type ecoord;
...
@@ -34,200 +34,200 @@ typedef VECTOR2I::extended_type ecoord;
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
aA
,
const
SHAPE_CIRCLE
&
aB
,
int
aClearance
,
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
aA
,
const
SHAPE_CIRCLE
&
aB
,
int
aClearance
,
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
{
{
ecoord
min_dist
=
aClearance
+
aA
.
GetRadius
()
+
aB
.
GetRadius
();
ecoord
min_dist
=
aClearance
+
aA
.
GetRadius
()
+
aB
.
GetRadius
();
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
const
VECTOR2I
delta
=
aB
.
GetCenter
()
-
aA
.
GetCenter
();
ecoord
dist_sq
=
delta
.
SquaredEuclideanNorm
();
const
VECTOR2I
delta
=
aB
.
GetCenter
()
-
aA
.
GetCenter
();
if
(
dist_sq
>=
min_dist_sq
)
ecoord
dist_sq
=
delta
.
SquaredEuclideanNorm
();
return
false
;
if
(
aNeedMTV
)
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
min_dist_sq
-
dist_sq
)
)
+
1
);
return
true
;
if
(
dist_sq
>=
min_dist_sq
)
return
false
;
if
(
aNeedMTV
)
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
min_dist_sq
-
dist_sq
)
)
+
1
);
return
true
;
}
}
static
inline
bool
Collide
(
const
SHAPE_RECT
&
aA
,
const
SHAPE_CIRCLE
&
aB
,
int
aClearance
,
static
inline
bool
Collide
(
const
SHAPE_RECT
&
aA
,
const
SHAPE_CIRCLE
&
aB
,
int
aClearance
,
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
{
{
const
VECTOR2I
c
=
aB
.
GetCenter
();
const
VECTOR2I
c
=
aB
.
GetCenter
();
const
VECTOR2I
p0
=
aA
.
GetPosition
();
const
VECTOR2I
p0
=
aA
.
GetPosition
();
const
VECTOR2I
size
=
aA
.
GetSize
();
const
VECTOR2I
size
=
aA
.
GetSize
();
const
ecoord
r
=
aB
.
GetRadius
();
const
ecoord
r
=
aB
.
GetRadius
();
const
ecoord
min_dist
=
aClearance
+
r
;
const
ecoord
min_dist
=
aClearance
+
r
;
const
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
const
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
if
(
aA
.
BBox
(
0
).
Contains
(
c
)
)
if
(
aA
.
BBox
(
0
).
Contains
(
c
)
)
return
true
;
return
true
;
const
VECTOR2I
vts
[]
=
{
const
VECTOR2I
vts
[]
=
{
VECTOR2I
(
p0
.
x
,
p0
.
y
),
VECTOR2I
(
p0
.
x
,
p0
.
y
),
VECTOR2I
(
p0
.
x
,
p0
.
y
+
size
.
y
),
VECTOR2I
(
p0
.
x
,
p0
.
y
+
size
.
y
),
VECTOR2I
(
p0
.
x
+
size
.
x
,
p0
.
y
+
size
.
y
),
VECTOR2I
(
p0
.
x
+
size
.
x
,
p0
.
y
+
size
.
y
),
VECTOR2I
(
p0
.
x
+
size
.
x
,
p0
.
y
),
VECTOR2I
(
p0
.
x
+
size
.
x
,
p0
.
y
),
VECTOR2I
(
p0
.
x
,
p0
.
y
)
};
VECTOR2I
(
p0
.
x
,
p0
.
y
)
};
ecoord
nearest_seg_dist_sq
=
VECTOR2I
::
ECOORD_MAX
;
ecoord
nearest_seg_dist_sq
=
VECTOR2I
::
ECOORD_MAX
;
VECTOR2I
nearest
;
VECTOR2I
nearest
;
bool
inside
=
c
.
x
>=
p0
.
x
&&
c
.
x
<=
(
p0
.
x
+
size
.
x
)
bool
inside
=
c
.
x
>=
p0
.
x
&&
c
.
x
<=
(
p0
.
x
+
size
.
x
)
&&
c
.
y
>=
p0
.
y
&&
c
.
y
<=
(
p0
.
y
+
size
.
y
);
&&
c
.
y
>=
p0
.
y
&&
c
.
y
<=
(
p0
.
y
+
size
.
y
);
if
(
!
inside
)
if
(
!
inside
)
{
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
{
const
SEG
seg
(
vts
[
i
],
vts
[
i
+
1
]
);
const
SEG
seg
(
vts
[
i
],
vts
[
i
+
1
]
);
ecoord
dist_sq
=
seg
.
SquaredDistance
(
c
);
ecoord
dist_sq
=
seg
.
SquaredDistance
(
c
);
if
(
dist_sq
<
min_dist_sq
)
if
(
dist_sq
<
min_dist_sq
)
{
{
if
(
!
aNeedMTV
)
if
(
!
aNeedMTV
)
return
true
;
return
true
;
else
else
{
{
nearest
=
seg
.
NearestPoint
(
c
);
nearest
=
seg
.
NearestPoint
(
c
);
nearest_seg_dist_sq
=
dist_sq
;
nearest_seg_dist_sq
=
dist_sq
;
}
}
}
}
}
}
}
}
if
(
nearest_seg_dist_sq
>=
min_dist_sq
&&
!
inside
)
if
(
nearest_seg_dist_sq
>=
min_dist_sq
&&
!
inside
)
return
false
;
return
false
;
VECTOR2I
delta
=
c
-
nearest
;
VECTOR2I
delta
=
c
-
nearest
;
if
(
!
aNeedMTV
)
if
(
!
aNeedMTV
)
return
true
;
return
true
;
if
(
inside
)
if
(
inside
)
aMTV
=
-
delta
.
Resize
(
sqrt
(
abs
(
r
*
r
+
nearest_seg_dist_sq
)
+
1
)
);
aMTV
=
-
delta
.
Resize
(
sqrt
(
abs
(
r
*
r
+
nearest_seg_dist_sq
)
+
1
)
);
else
else
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
r
*
r
-
nearest_seg_dist_sq
)
+
1
)
);
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
r
*
r
-
nearest_seg_dist_sq
)
+
1
)
);
return
true
;
return
true
;
}
}
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
aA
,
const
SHAPE_LINE_CHAIN
&
aB
,
int
aClearance
,
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
aA
,
const
SHAPE_LINE_CHAIN
&
aB
,
int
aClearance
,
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
{
{
for
(
int
s
=
0
;
s
<
aB
.
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
aB
.
SegmentCount
();
s
++
)
{
{
if
(
aA
.
Collide
(
aB
.
CSegment
(
s
),
aClearance
)
)
if
(
aA
.
Collide
(
aB
.
CSegment
(
s
),
aClearance
)
)
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
static
inline
bool
Collide
(
const
SHAPE_LINE_CHAIN
&
aA
,
const
SHAPE_LINE_CHAIN
&
aB
,
int
aClearance
,
static
inline
bool
Collide
(
const
SHAPE_LINE_CHAIN
&
aA
,
const
SHAPE_LINE_CHAIN
&
aB
,
int
aClearance
,
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
{
{
for
(
int
i
=
0
;
i
<
aB
.
SegmentCount
();
i
++
)
for
(
int
i
=
0
;
i
<
aB
.
SegmentCount
();
i
++
)
if
(
aA
.
Collide
(
aB
.
CSegment
(
i
),
aClearance
)
)
if
(
aA
.
Collide
(
aB
.
CSegment
(
i
),
aClearance
)
)
return
true
;
return
true
;
return
false
;
return
false
;
}
}
static
inline
bool
Collide
(
const
SHAPE_RECT
&
aA
,
const
SHAPE_LINE_CHAIN
&
aB
,
int
aClearance
,
static
inline
bool
Collide
(
const
SHAPE_RECT
&
aA
,
const
SHAPE_LINE_CHAIN
&
aB
,
int
aClearance
,
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
{
{
for
(
int
s
=
0
;
s
<
aB
.
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
aB
.
SegmentCount
();
s
++
)
{
{
SEG
seg
=
aB
.
CSegment
(
s
);
SEG
seg
=
aB
.
CSegment
(
s
);
if
(
aA
.
Collide
(
seg
,
aClearance
)
)
if
(
aA
.
Collide
(
seg
,
aClearance
)
)
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
bool
CollideShapes
(
const
SHAPE
*
aA
,
const
SHAPE
*
aB
,
int
aClearance
,
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
bool
CollideShapes
(
const
SHAPE
*
aA
,
const
SHAPE
*
aB
,
int
aClearance
,
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
{
{
switch
(
aA
->
Type
()
)
switch
(
aA
->
Type
()
)
{
{
case
SH_RECT
:
case
SH_RECT
:
switch
(
aB
->
Type
()
)
switch
(
aB
->
Type
()
)
{
{
case
SH_CIRCLE
:
case
SH_CIRCLE
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
aA
),
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
aA
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
case
SH_LINE_CHAIN
:
case
SH_LINE_CHAIN
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
aA
),
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
aA
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
default:
default:
break
;
break
;
}
}
case
SH_CIRCLE
:
case
SH_CIRCLE
:
switch
(
aB
->
Type
()
)
switch
(
aB
->
Type
()
)
{
{
case
SH_RECT
:
case
SH_RECT
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
aB
),
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
aB
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aA
),
aClearance
,
aNeedMTV
,
aMTV
);
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aA
),
aClearance
,
aNeedMTV
,
aMTV
);
case
SH_CIRCLE
:
case
SH_CIRCLE
:
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aA
),
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aA
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
case
SH_LINE_CHAIN
:
case
SH_LINE_CHAIN
:
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aA
),
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aA
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
default:
default:
break
;
break
;
}
}
case
SH_LINE_CHAIN
:
case
SH_LINE_CHAIN
:
switch
(
aB
->
Type
()
)
switch
(
aB
->
Type
()
)
{
{
case
SH_RECT
:
case
SH_RECT
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
aB
),
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
aB
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aA
),
aClearance
,
aNeedMTV
,
aMTV
);
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aA
),
aClearance
,
aNeedMTV
,
aMTV
);
case
SH_CIRCLE
:
case
SH_CIRCLE
:
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aB
),
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
aB
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aA
),
aClearance
,
aNeedMTV
,
aMTV
);
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aA
),
aClearance
,
aNeedMTV
,
aMTV
);
case
SH_LINE_CHAIN
:
case
SH_LINE_CHAIN
:
return
Collide
(
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aA
),
return
Collide
(
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aA
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
aB
),
aClearance
,
aNeedMTV
,
aMTV
);
default:
default:
break
;
break
;
}
}
default:
default:
break
;
break
;
}
}
bool
unsupported_collision
=
true
;
bool
unsupported_collision
=
true
;
assert
(
unsupported_collision
==
false
);
assert
(
unsupported_collision
==
false
);
return
false
;
return
false
;
}
}
bool
SHAPE
::
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
,
VECTOR2I
&
aMTV
)
const
bool
SHAPE
::
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
,
VECTOR2I
&
aMTV
)
const
{
{
return
CollideShapes
(
this
,
aShape
,
aClerance
,
true
,
aMTV
);
return
CollideShapes
(
this
,
aShape
,
aClerance
,
true
,
aMTV
);
}
}
bool
SHAPE
::
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
)
const
bool
SHAPE
::
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
)
const
{
{
VECTOR2I
dummy
;
VECTOR2I
dummy
;
return
CollideShapes
(
this
,
aShape
,
aClerance
,
false
,
dummy
);
return
CollideShapes
(
this
,
aShape
,
aClerance
,
false
,
dummy
);
}
}
common/geometry/shape_line_chain.cpp
View file @
22045b61
...
@@ -30,491 +30,491 @@ using boost::optional;
...
@@ -30,491 +30,491 @@ using boost::optional;
bool
SHAPE_LINE_CHAIN
::
Collide
(
const
VECTOR2I
&
aP
,
int
aClearance
)
const
bool
SHAPE_LINE_CHAIN
::
Collide
(
const
VECTOR2I
&
aP
,
int
aClearance
)
const
{
{
assert
(
false
);
assert
(
false
);
return
false
;
return
false
;
}
}
bool
SHAPE_LINE_CHAIN
::
Collide
(
const
BOX2I
&
aBox
,
int
aClearance
)
const
bool
SHAPE_LINE_CHAIN
::
Collide
(
const
BOX2I
&
aBox
,
int
aClearance
)
const
{
{
assert
(
false
);
assert
(
false
);
return
false
;
return
false
;
}
}
bool
SHAPE_LINE_CHAIN
::
Collide
(
const
SEG
&
aSeg
,
int
aClearance
)
const
bool
SHAPE_LINE_CHAIN
::
Collide
(
const
SEG
&
aSeg
,
int
aClearance
)
const
{
{
BOX2I
box_a
(
aSeg
.
a
,
aSeg
.
b
-
aSeg
.
a
);
BOX2I
box_a
(
aSeg
.
a
,
aSeg
.
b
-
aSeg
.
a
);
BOX2I
::
ecoord_type
dist_sq
=
(
BOX2I
::
ecoord_type
)
aClearance
*
aClearance
;
BOX2I
::
ecoord_type
dist_sq
=
(
BOX2I
::
ecoord_type
)
aClearance
*
aClearance
;
for
(
int
i
=
0
;
i
<
SegmentCount
()
;
i
++
)
for
(
int
i
=
0
;
i
<
SegmentCount
()
;
i
++
)
{
{
const
SEG
&
s
=
CSegment
(
i
);
const
SEG
&
s
=
CSegment
(
i
);
BOX2I
box_b
(
s
.
a
,
s
.
b
-
s
.
a
);
BOX2I
box_b
(
s
.
a
,
s
.
b
-
s
.
a
);
BOX2I
::
ecoord_type
d
=
box_a
.
SquaredDistance
(
box_b
);
BOX2I
::
ecoord_type
d
=
box_a
.
SquaredDistance
(
box_b
);
if
(
d
<
dist_sq
)
if
(
d
<
dist_sq
)
{
{
if
(
s
.
Collide
(
aSeg
,
aClearance
)
)
if
(
s
.
Collide
(
aSeg
,
aClearance
)
)
return
true
;
return
true
;
}
}
}
}
return
false
;
return
false
;
}
}
const
SHAPE_LINE_CHAIN
SHAPE_LINE_CHAIN
::
Reverse
()
const
const
SHAPE_LINE_CHAIN
SHAPE_LINE_CHAIN
::
Reverse
()
const
{
{
SHAPE_LINE_CHAIN
a
(
*
this
);
SHAPE_LINE_CHAIN
a
(
*
this
);
reverse
(
a
.
m_points
.
begin
(),
a
.
m_points
.
end
()
);
reverse
(
a
.
m_points
.
begin
(),
a
.
m_points
.
end
()
);
a
.
m_closed
=
m_closed
;
a
.
m_closed
=
m_closed
;
return
a
;
return
a
;
}
}
int
SHAPE_LINE_CHAIN
::
Length
()
const
int
SHAPE_LINE_CHAIN
::
Length
()
const
{
{
int
l
=
0
;
int
l
=
0
;
for
(
int
i
=
0
;
i
<
SegmentCount
();
i
++
)
for
(
int
i
=
0
;
i
<
SegmentCount
();
i
++
)
l
+=
CSegment
(
i
).
Length
();
l
+=
CSegment
(
i
).
Length
();
return
l
;
return
l
;
}
}
void
SHAPE_LINE_CHAIN
::
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
VECTOR2I
&
aP
)
void
SHAPE_LINE_CHAIN
::
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
VECTOR2I
&
aP
)
{
{
if
(
aEndIndex
<
0
)
if
(
aEndIndex
<
0
)
aEndIndex
+=
PointCount
();
aEndIndex
+=
PointCount
();
if
(
aStartIndex
<
0
)
if
(
aStartIndex
<
0
)
aStartIndex
+=
PointCount
();
aStartIndex
+=
PointCount
();
if
(
aStartIndex
==
aEndIndex
)
if
(
aStartIndex
==
aEndIndex
)
m_points
[
aStartIndex
]
=
aP
;
m_points
[
aStartIndex
]
=
aP
;
else
else
{
{
m_points
.
erase
(
m_points
.
begin
()
+
aStartIndex
+
1
,
m_points
.
begin
()
+
aEndIndex
+
1
);
m_points
.
erase
(
m_points
.
begin
()
+
aStartIndex
+
1
,
m_points
.
begin
()
+
aEndIndex
+
1
);
m_points
[
aStartIndex
]
=
aP
;
m_points
[
aStartIndex
]
=
aP
;
}
}
}
}
void
SHAPE_LINE_CHAIN
::
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
SHAPE_LINE_CHAIN
&
aLine
)
void
SHAPE_LINE_CHAIN
::
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
SHAPE_LINE_CHAIN
&
aLine
)
{
{
if
(
aEndIndex
<
0
)
if
(
aEndIndex
<
0
)
aEndIndex
+=
PointCount
();
aEndIndex
+=
PointCount
();
if
(
aStartIndex
<
0
)
if
(
aStartIndex
<
0
)
aStartIndex
+=
PointCount
();
aStartIndex
+=
PointCount
();
m_points
.
erase
(
m_points
.
begin
()
+
aStartIndex
,
m_points
.
begin
()
+
aEndIndex
+
1
);
m_points
.
erase
(
m_points
.
begin
()
+
aStartIndex
,
m_points
.
begin
()
+
aEndIndex
+
1
);
m_points
.
insert
(
m_points
.
begin
()
+
aStartIndex
,
aLine
.
m_points
.
begin
(),
aLine
.
m_points
.
end
()
);
m_points
.
insert
(
m_points
.
begin
()
+
aStartIndex
,
aLine
.
m_points
.
begin
(),
aLine
.
m_points
.
end
()
);
}
}
void
SHAPE_LINE_CHAIN
::
Remove
(
int
aStartIndex
,
int
aEndIndex
)
void
SHAPE_LINE_CHAIN
::
Remove
(
int
aStartIndex
,
int
aEndIndex
)
{
{
if
(
aEndIndex
<
0
)
if
(
aEndIndex
<
0
)
aEndIndex
+=
PointCount
();
aEndIndex
+=
PointCount
();
if
(
aStartIndex
<
0
)
if
(
aStartIndex
<
0
)
aStartIndex
+=
PointCount
();
aStartIndex
+=
PointCount
();
m_points
.
erase
(
m_points
.
begin
()
+
aStartIndex
,
m_points
.
begin
()
+
aEndIndex
+
1
);
m_points
.
erase
(
m_points
.
begin
()
+
aStartIndex
,
m_points
.
begin
()
+
aEndIndex
+
1
);
}
}
int
SHAPE_LINE_CHAIN
::
Distance
(
const
VECTOR2I
&
aP
)
const
int
SHAPE_LINE_CHAIN
::
Distance
(
const
VECTOR2I
&
aP
)
const
{
{
int
d
=
INT_MAX
;
int
d
=
INT_MAX
;
for
(
int
s
=
0
;
s
<
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
SegmentCount
();
s
++
)
d
=
min
(
d
,
CSegment
(
s
).
Distance
(
aP
)
);
d
=
min
(
d
,
CSegment
(
s
).
Distance
(
aP
)
);
return
d
;
return
d
;
}
}
int
SHAPE_LINE_CHAIN
::
Split
(
const
VECTOR2I
&
aP
)
int
SHAPE_LINE_CHAIN
::
Split
(
const
VECTOR2I
&
aP
)
{
{
int
ii
=
-
1
;
int
ii
=
-
1
;
int
min_dist
=
2
;
int
min_dist
=
2
;
ii
=
Find
(
aP
);
ii
=
Find
(
aP
);
if
(
ii
>=
0
)
if
(
ii
>=
0
)
return
ii
;
return
ii
;
for
(
int
s
=
0
;
s
<
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
SegmentCount
();
s
++
)
{
{
const
SEG
seg
=
CSegment
(
s
);
const
SEG
seg
=
CSegment
(
s
);
int
dist
=
seg
.
Distance
(
aP
);
int
dist
=
seg
.
Distance
(
aP
);
// make sure we are not producing a 'slightly concave' primitive. This might happen
// make sure we are not producing a 'slightly concave' primitive. This might happen
// if aP lies very close to one of already existing points.
// if aP lies very close to one of already existing points.
if
(
dist
<
min_dist
&&
seg
.
a
!=
aP
&&
seg
.
b
!=
aP
)
if
(
dist
<
min_dist
&&
seg
.
a
!=
aP
&&
seg
.
b
!=
aP
)
{
{
min_dist
=
dist
;
min_dist
=
dist
;
ii
=
s
;
ii
=
s
;
}
}
}
}
if
(
ii
>=
0
)
if
(
ii
>=
0
)
{
{
m_points
.
insert
(
m_points
.
begin
()
+
ii
+
1
,
aP
);
m_points
.
insert
(
m_points
.
begin
()
+
ii
+
1
,
aP
);
return
ii
+
1
;
return
ii
+
1
;
}
}
return
-
1
;
return
-
1
;
}
}
int
SHAPE_LINE_CHAIN
::
Find
(
const
VECTOR2I
&
aP
)
const
int
SHAPE_LINE_CHAIN
::
Find
(
const
VECTOR2I
&
aP
)
const
{
{
for
(
int
s
=
0
;
s
<
PointCount
();
s
++
)
for
(
int
s
=
0
;
s
<
PointCount
();
s
++
)
if
(
CPoint
(
s
)
==
aP
)
if
(
CPoint
(
s
)
==
aP
)
return
s
;
return
s
;
return
-
1
;
return
-
1
;
}
}
const
SHAPE_LINE_CHAIN
SHAPE_LINE_CHAIN
::
Slice
(
int
aStartIndex
,
int
aEndIndex
)
const
const
SHAPE_LINE_CHAIN
SHAPE_LINE_CHAIN
::
Slice
(
int
aStartIndex
,
int
aEndIndex
)
const
{
{
SHAPE_LINE_CHAIN
rv
;
SHAPE_LINE_CHAIN
rv
;
if
(
aEndIndex
<
0
)
if
(
aEndIndex
<
0
)
aEndIndex
+=
PointCount
();
aEndIndex
+=
PointCount
();
if
(
aStartIndex
<
0
)
if
(
aStartIndex
<
0
)
aStartIndex
+=
PointCount
();
aStartIndex
+=
PointCount
();
for
(
int
i
=
aStartIndex
;
i
<=
aEndIndex
;
i
++
)
for
(
int
i
=
aStartIndex
;
i
<=
aEndIndex
;
i
++
)
rv
.
Append
(
m_points
[
i
]
);
rv
.
Append
(
m_points
[
i
]
);
return
rv
;
return
rv
;
}
}
struct
compareOriginDistance
struct
compareOriginDistance
{
{
compareOriginDistance
(
VECTOR2I
&
aOrigin
)
:
compareOriginDistance
(
VECTOR2I
&
aOrigin
)
:
m_origin
(
aOrigin
)
{};
m_origin
(
aOrigin
)
{};
bool
operator
()(
const
SHAPE_LINE_CHAIN
::
Intersection
&
aA
,
bool
operator
()(
const
SHAPE_LINE_CHAIN
::
Intersection
&
aA
,
const
SHAPE_LINE_CHAIN
::
Intersection
&
aB
)
const
SHAPE_LINE_CHAIN
::
Intersection
&
aB
)
{
{
return
(
m_origin
-
aA
.
p
).
EuclideanNorm
()
<
(
m_origin
-
aB
.
p
).
EuclideanNorm
();
return
(
m_origin
-
aA
.
p
).
EuclideanNorm
()
<
(
m_origin
-
aB
.
p
).
EuclideanNorm
();
}
}
VECTOR2I
m_origin
;
VECTOR2I
m_origin
;
};
};
int
SHAPE_LINE_CHAIN
::
Intersect
(
const
SEG
&
aSeg
,
Intersections
&
aIp
)
const
int
SHAPE_LINE_CHAIN
::
Intersect
(
const
SEG
&
aSeg
,
Intersections
&
aIp
)
const
{
{
for
(
int
s
=
0
;
s
<
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
SegmentCount
();
s
++
)
{
{
OPT_VECTOR2I
p
=
CSegment
(
s
).
Intersect
(
aSeg
);
OPT_VECTOR2I
p
=
CSegment
(
s
).
Intersect
(
aSeg
);
if
(
p
)
if
(
p
)
{
{
Intersection
is
;
Intersection
is
;
is
.
our
=
CSegment
(
s
);
is
.
our
=
CSegment
(
s
);
is
.
their
=
aSeg
;
is
.
their
=
aSeg
;
is
.
p
=
*
p
;
is
.
p
=
*
p
;
aIp
.
push_back
(
is
);
aIp
.
push_back
(
is
);
}
}
}
}
compareOriginDistance
comp
(
aSeg
.
a
);
compareOriginDistance
comp
(
aSeg
.
a
);
sort
(
aIp
.
begin
(),
aIp
.
end
(),
comp
);
sort
(
aIp
.
begin
(),
aIp
.
end
(),
comp
);
return
aIp
.
size
();
return
aIp
.
size
();
}
}
int
SHAPE_LINE_CHAIN
::
Intersect
(
const
SHAPE_LINE_CHAIN
&
aChain
,
Intersections
&
aIp
)
const
int
SHAPE_LINE_CHAIN
::
Intersect
(
const
SHAPE_LINE_CHAIN
&
aChain
,
Intersections
&
aIp
)
const
{
{
BOX2I
bb_other
=
aChain
.
BBox
();
BOX2I
bb_other
=
aChain
.
BBox
();
for
(
int
s1
=
0
;
s1
<
SegmentCount
();
s1
++
)
for
(
int
s1
=
0
;
s1
<
SegmentCount
();
s1
++
)
{
{
const
SEG
&
a
=
CSegment
(
s1
);
const
SEG
&
a
=
CSegment
(
s1
);
const
BOX2I
bb_cur
(
a
.
a
,
a
.
b
-
a
.
a
);
const
BOX2I
bb_cur
(
a
.
a
,
a
.
b
-
a
.
a
);
if
(
!
bb_other
.
Intersects
(
bb_cur
)
)
if
(
!
bb_other
.
Intersects
(
bb_cur
)
)
continue
;
continue
;
for
(
int
s2
=
0
;
s2
<
aChain
.
SegmentCount
();
s2
++
)
for
(
int
s2
=
0
;
s2
<
aChain
.
SegmentCount
();
s2
++
)
{
{
const
SEG
&
b
=
aChain
.
CSegment
(
s2
);
const
SEG
&
b
=
aChain
.
CSegment
(
s2
);
Intersection
is
;
Intersection
is
;
if
(
a
.
Collinear
(
b
)
)
if
(
a
.
Collinear
(
b
)
)
{
{
if
(
a
.
Contains
(
b
.
a
)
)
{
is
.
p
=
b
.
a
;
aIp
.
push_back
(
is
);
}
if
(
a
.
Contains
(
b
.
a
)
)
{
is
.
p
=
b
.
a
;
aIp
.
push_back
(
is
);
}
if
(
a
.
Contains
(
b
.
b
)
)
{
is
.
p
=
b
.
b
;
aIp
.
push_back
(
is
);
}
if
(
a
.
Contains
(
b
.
b
)
)
{
is
.
p
=
b
.
b
;
aIp
.
push_back
(
is
);
}
if
(
b
.
Contains
(
a
.
a
)
)
{
is
.
p
=
a
.
a
;
aIp
.
push_back
(
is
);
}
if
(
b
.
Contains
(
a
.
a
)
)
{
is
.
p
=
a
.
a
;
aIp
.
push_back
(
is
);
}
if
(
b
.
Contains
(
a
.
b
)
)
{
is
.
p
=
a
.
b
;
aIp
.
push_back
(
is
);
}
if
(
b
.
Contains
(
a
.
b
)
)
{
is
.
p
=
a
.
b
;
aIp
.
push_back
(
is
);
}
}
}
else
else
{
{
OPT_VECTOR2I
p
=
a
.
Intersect
(
b
);
OPT_VECTOR2I
p
=
a
.
Intersect
(
b
);
if
(
p
)
if
(
p
)
{
{
is
.
p
=
*
p
;
is
.
p
=
*
p
;
is
.
our
=
a
;
is
.
our
=
a
;
is
.
their
=
b
;
is
.
their
=
b
;
aIp
.
push_back
(
is
);
aIp
.
push_back
(
is
);
}
}
}
}
}
}
}
}
return
aIp
.
size
();
return
aIp
.
size
();
for
(
int
s1
=
0
;
s1
<
SegmentCount
();
s1
++
)
for
(
int
s1
=
0
;
s1
<
SegmentCount
();
s1
++
)
{
{
for
(
int
s2
=
0
;
s2
<
aChain
.
SegmentCount
();
s2
++
)
for
(
int
s2
=
0
;
s2
<
aChain
.
SegmentCount
();
s2
++
)
{
{
const
SEG
&
a
=
CSegment
(
s1
);
const
SEG
&
a
=
CSegment
(
s1
);
const
SEG
&
b
=
aChain
.
CSegment
(
s2
);
const
SEG
&
b
=
aChain
.
CSegment
(
s2
);
OPT_VECTOR2I
p
=
a
.
Intersect
(
b
);
OPT_VECTOR2I
p
=
a
.
Intersect
(
b
);
Intersection
is
;
Intersection
is
;
if
(
p
)
if
(
p
)
{
{
is
.
p
=
*
p
;
is
.
p
=
*
p
;
is
.
our
=
a
;
is
.
our
=
a
;
is
.
their
=
b
;
is
.
their
=
b
;
aIp
.
push_back
(
is
);
aIp
.
push_back
(
is
);
}
}
else
if
(
a
.
Collinear
(
b
)
)
else
if
(
a
.
Collinear
(
b
)
)
{
{
if
(
a
.
a
!=
b
.
a
&&
a
.
a
!=
b
.
b
&&
b
.
Contains
(
a
.
a
)
)
if
(
a
.
a
!=
b
.
a
&&
a
.
a
!=
b
.
b
&&
b
.
Contains
(
a
.
a
)
)
{
{
is
.
p
=
a
.
a
;
is
.
p
=
a
.
a
;
is
.
our
=
a
;
is
.
our
=
a
;
is
.
their
=
b
;
is
.
their
=
b
;
aIp
.
push_back
(
is
);
aIp
.
push_back
(
is
);
}
}
else
if
(
a
.
b
!=
b
.
a
&&
a
.
b
!=
b
.
b
&&
b
.
Contains
(
a
.
b
)
)
else
if
(
a
.
b
!=
b
.
a
&&
a
.
b
!=
b
.
b
&&
b
.
Contains
(
a
.
b
)
)
{
{
is
.
p
=
a
.
b
;
is
.
p
=
a
.
b
;
is
.
our
=
a
;
is
.
our
=
a
;
is
.
their
=
b
;
is
.
their
=
b
;
aIp
.
push_back
(
is
);
aIp
.
push_back
(
is
);
}
}
}
}
}
}
}
}
return
aIp
.
size
();
return
aIp
.
size
();
}
}
int
SHAPE_LINE_CHAIN
::
PathLength
(
const
VECTOR2I
&
aP
)
const
int
SHAPE_LINE_CHAIN
::
PathLength
(
const
VECTOR2I
&
aP
)
const
{
{
int
sum
=
0
;
int
sum
=
0
;
for
(
int
i
=
0
;
i
<
SegmentCount
();
i
++
)
for
(
int
i
=
0
;
i
<
SegmentCount
();
i
++
)
{
{
const
SEG
seg
=
CSegment
(
i
);
const
SEG
seg
=
CSegment
(
i
);
int
d
=
seg
.
Distance
(
aP
);
int
d
=
seg
.
Distance
(
aP
);
if
(
d
<=
1
)
if
(
d
<=
1
)
{
{
sum
+=
(
aP
-
seg
.
a
).
EuclideanNorm
();
sum
+=
(
aP
-
seg
.
a
).
EuclideanNorm
();
return
sum
;
return
sum
;
}
}
else
else
sum
+=
seg
.
Length
();
sum
+=
seg
.
Length
();
}
}
return
-
1
;
return
-
1
;
}
}
bool
SHAPE_LINE_CHAIN
::
PointInside
(
const
VECTOR2I
&
aP
)
const
bool
SHAPE_LINE_CHAIN
::
PointInside
(
const
VECTOR2I
&
aP
)
const
{
{
if
(
!
m_closed
||
SegmentCount
()
<
3
)
if
(
!
m_closed
||
SegmentCount
()
<
3
)
return
false
;
return
false
;
int
cur
=
CSegment
(
0
).
Side
(
aP
);
int
cur
=
CSegment
(
0
).
Side
(
aP
);
if
(
cur
==
0
)
if
(
cur
==
0
)
return
false
;
return
false
;
for
(
int
i
=
1
;
i
<
SegmentCount
();
i
++
)
for
(
int
i
=
1
;
i
<
SegmentCount
();
i
++
)
{
{
const
SEG
s
=
CSegment
(
i
);
const
SEG
s
=
CSegment
(
i
);
if
(
aP
==
s
.
a
||
aP
==
s
.
b
)
// edge does not belong to the interior!
if
(
aP
==
s
.
a
||
aP
==
s
.
b
)
// edge does not belong to the interior!
return
false
;
return
false
;
if
(
s
.
Side
(
aP
)
!=
cur
)
if
(
s
.
Side
(
aP
)
!=
cur
)
return
false
;
return
false
;
}
}
return
true
;
return
true
;
}
}
bool
SHAPE_LINE_CHAIN
::
PointOnEdge
(
const
VECTOR2I
&
aP
)
const
bool
SHAPE_LINE_CHAIN
::
PointOnEdge
(
const
VECTOR2I
&
aP
)
const
{
{
if
(
SegmentCount
()
<
1
)
if
(
SegmentCount
()
<
1
)
return
m_points
[
0
]
==
aP
;
return
m_points
[
0
]
==
aP
;
for
(
int
i
=
1
;
i
<
SegmentCount
();
i
++
)
for
(
int
i
=
1
;
i
<
SegmentCount
();
i
++
)
{
{
const
SEG
s
=
CSegment
(
i
);
const
SEG
s
=
CSegment
(
i
);
if
(
s
.
a
==
aP
||
s
.
b
==
aP
)
return
true
;
if
(
s
.
Distance
(
aP
)
<=
1
)
if
(
s
.
a
==
aP
||
s
.
b
==
aP
)
return
true
;
return
true
;
}
return
false
;
if
(
s
.
Distance
(
aP
)
<=
1
)
return
true
;
}
return
false
;
}
}
const
optional
<
SHAPE_LINE_CHAIN
::
Intersection
>
SHAPE_LINE_CHAIN
::
SelfIntersecting
()
const
const
optional
<
SHAPE_LINE_CHAIN
::
Intersection
>
SHAPE_LINE_CHAIN
::
SelfIntersecting
()
const
{
{
for
(
int
s1
=
0
;
s1
<
SegmentCount
();
s1
++
)
for
(
int
s1
=
0
;
s1
<
SegmentCount
();
s1
++
)
{
{
for
(
int
s2
=
s1
+
1
;
s2
<
SegmentCount
();
s2
++
)
for
(
int
s2
=
s1
+
1
;
s2
<
SegmentCount
();
s2
++
)
{
{
const
VECTOR2I
s2a
=
CSegment
(
s2
).
a
,
s2b
=
CSegment
(
s2
).
b
;
const
VECTOR2I
s2a
=
CSegment
(
s2
).
a
,
s2b
=
CSegment
(
s2
).
b
;
if
(
s1
+
1
!=
s2
&&
CSegment
(
s1
).
Contains
(
s2a
)
)
if
(
s1
+
1
!=
s2
&&
CSegment
(
s1
).
Contains
(
s2a
)
)
{
{
Intersection
is
;
Intersection
is
;
is
.
our
=
CSegment
(
s1
);
is
.
our
=
CSegment
(
s1
);
is
.
their
=
CSegment
(
s2
);
is
.
their
=
CSegment
(
s2
);
is
.
p
=
s2a
;
is
.
p
=
s2a
;
return
is
;
return
is
;
}
}
else
if
(
CSegment
(
s1
).
Contains
(
s2b
)
)
else
if
(
CSegment
(
s1
).
Contains
(
s2b
)
)
{
{
Intersection
is
;
Intersection
is
;
is
.
our
=
CSegment
(
s1
);
is
.
our
=
CSegment
(
s1
);
is
.
their
=
CSegment
(
s2
);
is
.
their
=
CSegment
(
s2
);
is
.
p
=
s2b
;
is
.
p
=
s2b
;
return
is
;
return
is
;
}
}
else
else
{
{
OPT_VECTOR2I
p
=
CSegment
(
s1
).
Intersect
(
CSegment
(
s2
),
true
);
OPT_VECTOR2I
p
=
CSegment
(
s1
).
Intersect
(
CSegment
(
s2
),
true
);
if
(
p
)
if
(
p
)
{
{
Intersection
is
;
Intersection
is
;
is
.
our
=
CSegment
(
s1
);
is
.
our
=
CSegment
(
s1
);
is
.
their
=
CSegment
(
s2
);
is
.
their
=
CSegment
(
s2
);
is
.
p
=
*
p
;
is
.
p
=
*
p
;
return
is
;
return
is
;
}
}
}
}
}
}
}
}
return
optional
<
Intersection
>
();
return
optional
<
Intersection
>
();
}
}
SHAPE_LINE_CHAIN
&
SHAPE_LINE_CHAIN
::
Simplify
()
SHAPE_LINE_CHAIN
&
SHAPE_LINE_CHAIN
::
Simplify
()
{
{
vector
<
VECTOR2I
>
pts_unique
;
vector
<
VECTOR2I
>
pts_unique
;
if
(
PointCount
()
<
2
)
if
(
PointCount
()
<
2
)
{
{
return
*
this
;
return
*
this
;
}
}
else
if
(
PointCount
()
==
2
)
else
if
(
PointCount
()
==
2
)
{
{
if
(
m_points
[
0
]
==
m_points
[
1
]
)
if
(
m_points
[
0
]
==
m_points
[
1
]
)
m_points
.
erase
(
m_points
.
end
()
);
m_points
.
erase
(
m_points
.
end
()
);
return
*
this
;
return
*
this
;
}
}
int
i
=
0
;
int
i
=
0
;
int
np
=
PointCount
();
int
np
=
PointCount
();
// stage 1: eliminate duplicate vertices
// stage 1: eliminate duplicate vertices
while
(
i
<
np
)
while
(
i
<
np
)
{
{
int
j
=
i
+
1
;
int
j
=
i
+
1
;
while
(
j
<
np
&&
CPoint
(
i
)
==
CPoint
(
j
)
)
while
(
j
<
np
&&
CPoint
(
i
)
==
CPoint
(
j
)
)
j
++
;
j
++
;
pts_unique
.
push_back
(
CPoint
(
i
)
);
pts_unique
.
push_back
(
CPoint
(
i
)
);
i
=
j
;
i
=
j
;
}
}
m_points
.
clear
();
m_points
.
clear
();
np
=
pts_unique
.
size
();
np
=
pts_unique
.
size
();
i
=
0
;
i
=
0
;
// stage 1: eliminate collinear segments
// stage 1: eliminate collinear segments
while
(
i
<
np
-
2
)
while
(
i
<
np
-
2
)
{
{
const
VECTOR2I
p0
=
pts_unique
[
i
];
const
VECTOR2I
p0
=
pts_unique
[
i
];
const
VECTOR2I
p1
=
pts_unique
[
i
+
1
];
const
VECTOR2I
p1
=
pts_unique
[
i
+
1
];
int
n
=
i
;
int
n
=
i
;
while
(
n
<
np
-
2
&&
SEG
(
p0
,
p1
).
LineDistance
(
pts_unique
[
n
+
2
]
)
<=
1
)
while
(
n
<
np
-
2
&&
SEG
(
p0
,
p1
).
LineDistance
(
pts_unique
[
n
+
2
]
)
<=
1
)
n
++
;
n
++
;
m_points
.
push_back
(
p0
);
m_points
.
push_back
(
p0
);
if
(
n
>
i
)
if
(
n
>
i
)
i
=
n
;
i
=
n
;
if
(
n
==
np
)
if
(
n
==
np
)
{
{
m_points
.
push_back
(
pts_unique
[
n
-
1
]
);
m_points
.
push_back
(
pts_unique
[
n
-
1
]
);
return
*
this
;
return
*
this
;
}
}
i
++
;
i
++
;
}
}
if
(
np
>
1
)
if
(
np
>
1
)
m_points
.
push_back
(
pts_unique
[
np
-
2
]
);
m_points
.
push_back
(
pts_unique
[
np
-
2
]
);
m_points
.
push_back
(
pts_unique
[
np
-
1
]
);
m_points
.
push_back
(
pts_unique
[
np
-
1
]
);
return
*
this
;
return
*
this
;
}
}
const
VECTOR2I
SHAPE_LINE_CHAIN
::
NearestPoint
(
const
VECTOR2I
&
aP
)
const
const
VECTOR2I
SHAPE_LINE_CHAIN
::
NearestPoint
(
const
VECTOR2I
&
aP
)
const
{
{
int
min_d
=
INT_MAX
;
int
min_d
=
INT_MAX
;
int
nearest
=
0
;
int
nearest
=
0
;
for
(
int
i
=
0
;
i
<
SegmentCount
();
i
++
)
for
(
int
i
=
0
;
i
<
SegmentCount
();
i
++
)
{
{
int
d
=
CSegment
(
i
).
Distance
(
aP
);
int
d
=
CSegment
(
i
).
Distance
(
aP
);
if
(
d
<
min_d
)
if
(
d
<
min_d
)
{
{
min_d
=
d
;
min_d
=
d
;
nearest
=
i
;
nearest
=
i
;
}
}
}
}
return
CSegment
(
nearest
).
NearestPoint
(
aP
);
return
CSegment
(
nearest
).
NearestPoint
(
aP
);
}
}
const
string
SHAPE_LINE_CHAIN
::
Format
()
const
const
string
SHAPE_LINE_CHAIN
::
Format
()
const
{
{
stringstream
ss
;
stringstream
ss
;
ss
<<
m_points
.
size
()
<<
" "
<<
(
m_closed
?
1
:
0
)
<<
" "
;
ss
<<
m_points
.
size
()
<<
" "
<<
(
m_closed
?
1
:
0
)
<<
" "
;
for
(
int
i
=
0
;
i
<
PointCount
();
i
++
)
ss
<<
m_points
[
i
].
x
<<
" "
<<
m_points
[
i
].
y
<<
" "
;
// Format() << " ";
for
(
int
i
=
0
;
i
<
PointCount
();
i
++
)
return
ss
.
str
();
ss
<<
m_points
[
i
].
x
<<
" "
<<
m_points
[
i
].
y
<<
" "
;
// Format() << " ";
return
ss
.
str
();
}
}
common/system/fcontext.s
View file @
22045b61
/*
/*
Boost::Context assembly wrapper - done to avoid compiling the whole boost binary library
Boost::Context assembly wrapper - done to avoid compiling the whole boost binary library
which may be unpleasant, in particular under Windows (we don't support VC++, while boost::context
which may be unpleasant, in particular under Windows (we don't support VC++, while boost::context
does not support mingw */
does not support mingw */
#ifdef __APPLE__
#ifdef __APPLE__
...
...
common/system/make_i386_pe_gas.S
View file @
22045b61
...
@@ -9,39 +9,39 @@
...
@@ -9,39 +9,39 @@
.align 2
.align 2
_make_fcontext:
_make_fcontext:
mov 0x4(%esp),%eax
mov 0x4(%esp),%eax
lea -0x34(%eax),%eax
lea -0x34(%eax),%eax
and $0xfffffff0,%eax
and $0xfffffff0,%eax
mov 0x4(%esp),%ecx
mov 0x4(%esp),%ecx
mov %ecx,0x18(%eax)
mov %ecx,0x18(%eax)
mov 0x8(%esp),%edx
mov 0x8(%esp),%edx
mov %edx,0x1c(%eax)
mov %edx,0x1c(%eax)
neg %edx
neg %edx
lea (%edx,%ecx,1),%ecx
lea (%edx,%ecx,1),%ecx
mov %ecx,0x20(%eax)
mov %ecx,0x20(%eax)
mov 0xc(%esp),%ecx
mov 0xc(%esp),%ecx
mov %ecx,0x14(%eax)
mov %ecx,0x14(%eax)
stmxcsr 0x2c(%eax)
stmxcsr 0x2c(%eax)
fnstcw 0x30(%eax)
fnstcw 0x30(%eax)
lea -0x1c(%eax),%edx
lea -0x1c(%eax),%edx
mov %edx,0x10(%eax)
mov %edx,0x10(%eax)
mov $0x0,%ecx
mov $0x0,%ecx
mov %ecx,(%edx)
mov %ecx,(%edx)
mov %fs:0x18,%ecx
mov %fs:0x18,%ecx
mov (%ecx),%edx
mov (%ecx),%edx
inc %edx
inc %edx
je _make_fcontext+0x4c // <_make_fcontext+0x4c>
je _make_fcontext+0x4c // <_make_fcontext+0x4c>
dec %edx
dec %edx
xchg %edx,%ecx
xchg %edx,%ecx
jmp _make_fcontext+0x42 // <_make_fcontext+0x42>
jmp _make_fcontext+0x42 // <_make_fcontext+0x42>
mov 0x4(%ecx),%ecx
mov 0x4(%ecx),%ecx
mov 0x10(%eax),%edx
mov 0x10(%eax),%edx
mov %ecx,0x18(%edx)
mov %ecx,0x18(%edx)
mov $0xffffffff,%ecx
mov $0xffffffff,%ecx
mov %ecx,0x14(%edx)
mov %ecx,0x14(%edx)
lea 0x14(%edx),%ecx
lea 0x14(%edx),%ecx
mov %ecx,0x24(%eax)
mov %ecx,0x24(%eax)
ret
ret
finish:
finish:
xor %eax,%eax
xor %eax,%eax
...
...
common/tool/context_menu.cpp
View file @
22045b61
...
@@ -31,14 +31,14 @@
...
@@ -31,14 +31,14 @@
CONTEXT_MENU
::
CONTEXT_MENU
()
:
CONTEXT_MENU
::
CONTEXT_MENU
()
:
m_titleSet
(
false
),
m_handler
(
this
),
m_tool
(
NULL
)
m_titleSet
(
false
),
m_handler
(
this
),
m_tool
(
NULL
)
{
{
m_menu
.
Connect
(
wxEVT_MENU_HIGHLIGHT
,
wxEventHandler
(
CMEventHandler
::
onEvent
),
m_menu
.
Connect
(
wxEVT_MENU_HIGHLIGHT
,
wxEventHandler
(
CMEventHandler
::
onEvent
),
NULL
,
&
m_handler
);
NULL
,
&
m_handler
);
m_menu
.
Connect
(
wxEVT_COMMAND_MENU_SELECTED
,
wxEventHandler
(
CMEventHandler
::
onEvent
),
m_menu
.
Connect
(
wxEVT_COMMAND_MENU_SELECTED
,
wxEventHandler
(
CMEventHandler
::
onEvent
),
NULL
,
&
m_handler
);
NULL
,
&
m_handler
);
// Workaround for the case when mouse cursor never reaches menu (it hangs up tools using menu)
// Workaround for the case when mouse cursor never reaches menu (it hangs up tools using menu)
wxMenuEvent
menuEvent
(
wxEVT_MENU_HIGHLIGHT
,
-
1
,
&
m_menu
);
wxMenuEvent
menuEvent
(
wxEVT_MENU_HIGHLIGHT
,
-
1
,
&
m_menu
);
m_menu
.
AddPendingEvent
(
menuEvent
);
m_menu
.
AddPendingEvent
(
menuEvent
);
}
}
...
@@ -72,16 +72,16 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
...
@@ -72,16 +72,16 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
// TODO handle an empty string (remove title and separator)
// TODO handle an empty string (remove title and separator)
// Unfortunately wxMenu::SetTitle() does nothing..
// Unfortunately wxMenu::SetTitle() does nothing..
if
(
m_titleSet
)
if
(
m_titleSet
)
{
{
m_menu
.
FindItemByPosition
(
0
)
->
SetItemLabel
(
aTitle
);
m_menu
.
FindItemByPosition
(
0
)
->
SetItemLabel
(
aTitle
);
}
}
else
else
{
{
m_menu
.
InsertSeparator
(
0
);
m_menu
.
InsertSeparator
(
0
);
m_menu
.
Insert
(
0
,
new
wxMenuItem
(
&
m_menu
,
-
1
,
aTitle
,
wxEmptyString
,
wxITEM_NORMAL
)
);
m_menu
.
Insert
(
0
,
new
wxMenuItem
(
&
m_menu
,
-
1
,
aTitle
,
wxEmptyString
,
wxITEM_NORMAL
)
);
m_titleSet
=
true
;
m_titleSet
=
true
;
}
}
}
}
...
@@ -92,7 +92,7 @@ void CONTEXT_MENU::Add( const wxString& aLabel, int aId )
...
@@ -92,7 +92,7 @@ void CONTEXT_MENU::Add( const wxString& aLabel, int aId )
wxLogWarning
(
wxT
(
"Adding more than one menu entry with the same ID may result in"
wxLogWarning
(
wxT
(
"Adding more than one menu entry with the same ID may result in"
"undefined behaviour"
)
);
"undefined behaviour"
)
);
#endif
#endif
m_menu
.
Append
(
new
wxMenuItem
(
&
m_menu
,
aId
,
aLabel
,
wxEmptyString
,
wxITEM_NORMAL
)
);
m_menu
.
Append
(
new
wxMenuItem
(
&
m_menu
,
aId
,
aLabel
,
wxEmptyString
,
wxITEM_NORMAL
)
);
}
}
...
@@ -104,7 +104,7 @@ void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
...
@@ -104,7 +104,7 @@ void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
if
(
aAction
.
HasHotKey
()
)
if
(
aAction
.
HasHotKey
()
)
menuEntry
=
wxString
(
(
aAction
.
GetMenuItem
()
+
'\t'
+
getHotKeyDescription
(
aAction
)
).
c_str
(),
menuEntry
=
wxString
(
(
aAction
.
GetMenuItem
()
+
'\t'
+
getHotKeyDescription
(
aAction
)
).
c_str
(),
wxConvUTF8
);
wxConvUTF8
);
else
else
menuEntry
=
wxString
(
aAction
.
GetMenuItem
().
c_str
(),
wxConvUTF8
);
menuEntry
=
wxString
(
aAction
.
GetMenuItem
().
c_str
(),
wxConvUTF8
);
...
@@ -117,13 +117,13 @@ void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
...
@@ -117,13 +117,13 @@ void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
void
CONTEXT_MENU
::
Clear
()
void
CONTEXT_MENU
::
Clear
()
{
{
m_titleSet
=
false
;
m_titleSet
=
false
;
// Remove all the entries from context menu
// Remove all the entries from context menu
for
(
unsigned
i
=
0
;
i
<
m_menu
.
GetMenuItemCount
();
++
i
)
for
(
unsigned
i
=
0
;
i
<
m_menu
.
GetMenuItemCount
();
++
i
)
m_menu
.
Destroy
(
m_menu
.
FindItemByPosition
(
0
)
);
m_menu
.
Destroy
(
m_menu
.
FindItemByPosition
(
0
)
);
m_toolActions
.
clear
();
m_toolActions
.
clear
();
}
}
...
...
common/tool/tool_base.cpp
View file @
22045b61
...
@@ -27,23 +27,23 @@
...
@@ -27,23 +27,23 @@
KiGfx
::
VIEW
*
TOOL_BASE
::
getView
()
const
KiGfx
::
VIEW
*
TOOL_BASE
::
getView
()
const
{
{
return
m_toolMgr
->
GetView
();
return
m_toolMgr
->
GetView
();
}
}
KiGfx
::
VIEW_CONTROLS
*
TOOL_BASE
::
getViewControls
()
const
KiGfx
::
VIEW_CONTROLS
*
TOOL_BASE
::
getViewControls
()
const
{
{
return
m_toolMgr
->
GetViewControls
();
return
m_toolMgr
->
GetViewControls
();
}
}
wxWindow
*
TOOL_BASE
::
getEditFrameInt
()
const
wxWindow
*
TOOL_BASE
::
getEditFrameInt
()
const
{
{
return
m_toolMgr
->
GetEditFrame
();
return
m_toolMgr
->
GetEditFrame
();
}
}
EDA_ITEM
*
TOOL_BASE
::
getModelInt
()
const
EDA_ITEM
*
TOOL_BASE
::
getModelInt
()
const
{
{
return
m_toolMgr
->
GetModel
();
return
m_toolMgr
->
GetModel
();
}
}
common/tool/tool_dispatcher.cpp
View file @
22045b61
...
@@ -42,52 +42,52 @@ using boost::optional;
...
@@ -42,52 +42,52 @@ using boost::optional;
///> Stores information about a mouse button state
///> Stores information about a mouse button state
struct
TOOL_DISPATCHER
::
ButtonState
struct
TOOL_DISPATCHER
::
ButtonState
{
{
ButtonState
(
TOOL_MouseButtons
aButton
,
const
wxEventType
&
aDownEvent
,
ButtonState
(
TOOL_MouseButtons
aButton
,
const
wxEventType
&
aDownEvent
,
const
wxEventType
&
aUpEvent
)
:
const
wxEventType
&
aUpEvent
)
:
button
(
aButton
),
button
(
aButton
),
downEvent
(
aDownEvent
),
downEvent
(
aDownEvent
),
upEvent
(
aUpEvent
)
upEvent
(
aUpEvent
)
{};
{};
///> Flag indicating that dragging is active for the given button.
///> Flag indicating that dragging is active for the given button.
bool
dragging
;
bool
dragging
;
///> Flag indicating that the given button is pressed.
///> Flag indicating that the given button is pressed.
bool
pressed
;
bool
pressed
;
///> Point where dragging has started (in world coordinates).
///> Point where dragging has started (in world coordinates).
VECTOR2D
dragOrigin
;
VECTOR2D
dragOrigin
;
///> Point where click event has occurred.
///> Point where click event has occurred.
VECTOR2D
downPosition
;
VECTOR2D
downPosition
;
///> Difference between drag origin point and current mouse position (expressed as distance in
///> Difference between drag origin point and current mouse position (expressed as distance in
///> pixels).
///> pixels).
double
dragMaxDelta
;
double
dragMaxDelta
;
///> Determines the mouse button for which information are stored.
///> Determines the mouse button for which information are stored.
TOOL_MouseButtons
button
;
TOOL_MouseButtons
button
;
///> The type of wxEvent that determines mouse button press.
///> The type of wxEvent that determines mouse button press.
wxEventType
downEvent
;
wxEventType
downEvent
;
///> The type of wxEvent that determines mouse button release.
///> The type of wxEvent that determines mouse button release.
wxEventType
upEvent
;
wxEventType
upEvent
;
///> Time stamp for the last mouse button press event.
///> Time stamp for the last mouse button press event.
wxLongLong
downTimestamp
;
wxLongLong
downTimestamp
;
///> Restores initial state.
///> Restores initial state.
void
Reset
()
void
Reset
()
{
{
dragging
=
false
;
dragging
=
false
;
pressed
=
false
;
pressed
=
false
;
}
}
};
};
TOOL_DISPATCHER
::
TOOL_DISPATCHER
(
TOOL_MANAGER
*
aToolMgr
,
PCB_BASE_FRAME
*
aEditFrame
)
:
TOOL_DISPATCHER
::
TOOL_DISPATCHER
(
TOOL_MANAGER
*
aToolMgr
,
PCB_BASE_FRAME
*
aEditFrame
)
:
m_toolMgr
(
aToolMgr
),
m_editFrame
(
aEditFrame
)
m_toolMgr
(
aToolMgr
),
m_editFrame
(
aEditFrame
)
{
{
m_buttons
.
push_back
(
new
ButtonState
(
MB_Left
,
wxEVT_LEFT_DOWN
,
wxEVT_LEFT_UP
)
);
m_buttons
.
push_back
(
new
ButtonState
(
MB_Left
,
wxEVT_LEFT_DOWN
,
wxEVT_LEFT_UP
)
);
m_buttons
.
push_back
(
new
ButtonState
(
MB_Right
,
wxEVT_RIGHT_DOWN
,
wxEVT_RIGHT_UP
)
);
m_buttons
.
push_back
(
new
ButtonState
(
MB_Right
,
wxEVT_RIGHT_DOWN
,
wxEVT_RIGHT_UP
)
);
...
@@ -99,135 +99,135 @@ TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditF
...
@@ -99,135 +99,135 @@ TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditF
TOOL_DISPATCHER
::~
TOOL_DISPATCHER
()
TOOL_DISPATCHER
::~
TOOL_DISPATCHER
()
{
{
BOOST_FOREACH
(
ButtonState
*
st
,
m_buttons
)
BOOST_FOREACH
(
ButtonState
*
st
,
m_buttons
)
delete
st
;
delete
st
;
}
}
void
TOOL_DISPATCHER
::
ResetState
()
void
TOOL_DISPATCHER
::
ResetState
()
{
{
BOOST_FOREACH
(
ButtonState
*
st
,
m_buttons
)
BOOST_FOREACH
(
ButtonState
*
st
,
m_buttons
)
st
->
Reset
();
st
->
Reset
();
}
}
KiGfx
::
VIEW
*
TOOL_DISPATCHER
::
getView
()
KiGfx
::
VIEW
*
TOOL_DISPATCHER
::
getView
()
{
{
return
m_editFrame
->
GetGalCanvas
()
->
GetView
();
return
m_editFrame
->
GetGalCanvas
()
->
GetView
();
}
}
bool
TOOL_DISPATCHER
::
handleMouseButton
(
wxEvent
&
aEvent
,
int
aIndex
,
bool
aMotion
)
bool
TOOL_DISPATCHER
::
handleMouseButton
(
wxEvent
&
aEvent
,
int
aIndex
,
bool
aMotion
)
{
{
ButtonState
*
st
=
m_buttons
[
aIndex
];
ButtonState
*
st
=
m_buttons
[
aIndex
];
wxEventType
type
=
aEvent
.
GetEventType
();
wxEventType
type
=
aEvent
.
GetEventType
();
optional
<
TOOL_EVENT
>
evt
;
optional
<
TOOL_EVENT
>
evt
;
bool
isClick
=
false
;
bool
isClick
=
false
;
bool
up
=
type
==
st
->
upEvent
;
bool
up
=
type
==
st
->
upEvent
;
bool
down
=
type
==
st
->
downEvent
;
bool
down
=
type
==
st
->
downEvent
;
int
mods
=
decodeModifiers
<
wxMouseEvent
>
(
static_cast
<
wxMouseEvent
*>
(
&
aEvent
)
);
int
mods
=
decodeModifiers
<
wxMouseEvent
>
(
static_cast
<
wxMouseEvent
*>
(
&
aEvent
)
);
int
args
=
st
->
button
|
mods
;
int
args
=
st
->
button
|
mods
;
if
(
down
)
// Handle mouse button press
if
(
down
)
// Handle mouse button press
{
{
st
->
downTimestamp
=
wxGetLocalTimeMillis
();
st
->
downTimestamp
=
wxGetLocalTimeMillis
();
st
->
dragOrigin
=
m_lastMousePos
;
st
->
dragOrigin
=
m_lastMousePos
;
st
->
downPosition
=
m_lastMousePos
;
st
->
downPosition
=
m_lastMousePos
;
st
->
dragMaxDelta
=
0
;
st
->
dragMaxDelta
=
0
;
st
->
pressed
=
true
;
st
->
pressed
=
true
;
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseDown
,
args
);
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseDown
,
args
);
}
}
else
if
(
up
)
// Handle mouse button release
else
if
(
up
)
// Handle mouse button release
{
{
st
->
pressed
=
false
;
st
->
pressed
=
false
;
if
(
st
->
dragging
)
if
(
st
->
dragging
)
{
{
wxLongLong
t
=
wxGetLocalTimeMillis
();
wxLongLong
t
=
wxGetLocalTimeMillis
();
// Determine if it was just a single click or beginning of dragging
// Determine if it was just a single click or beginning of dragging
if
(
t
-
st
->
downTimestamp
<
DragTimeThreshold
&&
if
(
t
-
st
->
downTimestamp
<
DragTimeThreshold
&&
st
->
dragMaxDelta
<
DragDistanceThreshold
)
st
->
dragMaxDelta
<
DragDistanceThreshold
)
isClick
=
true
;
isClick
=
true
;
else
else
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseUp
,
args
);
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseUp
,
args
);
}
}
else
else
isClick
=
true
;
isClick
=
true
;
if
(
isClick
)
if
(
isClick
)
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseClick
,
args
);
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseClick
,
args
);
st
->
dragging
=
false
;
st
->
dragging
=
false
;
}
}
if
(
st
->
pressed
&&
aMotion
)
if
(
st
->
pressed
&&
aMotion
)
{
{
st
->
dragging
=
true
;
st
->
dragging
=
true
;
double
dragPixelDistance
=
getView
()
->
ToScreen
(
m_lastMousePos
-
st
->
dragOrigin
,
false
).
EuclideanNorm
();
double
dragPixelDistance
=
getView
()
->
ToScreen
(
m_lastMousePos
-
st
->
dragOrigin
,
false
).
EuclideanNorm
();
st
->
dragMaxDelta
=
std
::
max
(
st
->
dragMaxDelta
,
dragPixelDistance
);
st
->
dragMaxDelta
=
std
::
max
(
st
->
dragMaxDelta
,
dragPixelDistance
);
wxLongLong
t
=
wxGetLocalTimeMillis
();
wxLongLong
t
=
wxGetLocalTimeMillis
();
if
(
t
-
st
->
downTimestamp
>
DragTimeThreshold
||
st
->
dragMaxDelta
>
DragDistanceThreshold
)
if
(
t
-
st
->
downTimestamp
>
DragTimeThreshold
||
st
->
dragMaxDelta
>
DragDistanceThreshold
)
{
{
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseDrag
,
args
);
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseDrag
,
args
);
evt
->
SetMouseDragOrigin
(
st
->
dragOrigin
);
evt
->
SetMouseDragOrigin
(
st
->
dragOrigin
);
evt
->
SetMouseDelta
(
m_lastMousePos
-
st
->
dragOrigin
);
evt
->
SetMouseDelta
(
m_lastMousePos
-
st
->
dragOrigin
);
}
}
}
}
if
(
evt
)
if
(
evt
)
{
{
evt
->
SetMousePosition
(
isClick
?
st
->
downPosition
:
m_lastMousePos
);
evt
->
SetMousePosition
(
isClick
?
st
->
downPosition
:
m_lastMousePos
);
m_toolMgr
->
ProcessEvent
(
*
evt
);
m_toolMgr
->
ProcessEvent
(
*
evt
);
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
void
TOOL_DISPATCHER
::
DispatchWxEvent
(
wxEvent
&
aEvent
)
void
TOOL_DISPATCHER
::
DispatchWxEvent
(
wxEvent
&
aEvent
)
{
{
bool
motion
=
false
,
buttonEvents
=
false
;
bool
motion
=
false
,
buttonEvents
=
false
;
optional
<
TOOL_EVENT
>
evt
;
optional
<
TOOL_EVENT
>
evt
;
int
type
=
aEvent
.
GetEventType
();
int
type
=
aEvent
.
GetEventType
();
// Mouse handling
// Mouse handling
if
(
type
==
wxEVT_MOTION
||
type
==
wxEVT_MOUSEWHEEL
||
if
(
type
==
wxEVT_MOTION
||
type
==
wxEVT_MOUSEWHEEL
||
type
==
wxEVT_LEFT_DOWN
||
type
==
wxEVT_LEFT_UP
||
type
==
wxEVT_LEFT_DOWN
||
type
==
wxEVT_LEFT_UP
||
type
==
wxEVT_MIDDLE_DOWN
||
type
==
wxEVT_MIDDLE_UP
||
type
==
wxEVT_MIDDLE_DOWN
||
type
==
wxEVT_MIDDLE_UP
||
type
==
wxEVT_RIGHT_DOWN
||
type
==
wxEVT_RIGHT_UP
||
type
==
wxEVT_RIGHT_DOWN
||
type
==
wxEVT_RIGHT_UP
||
// Event issued whem mouse retains position in screen coordinates,
// Event issued whem mouse retains position in screen coordinates,
// but changes in world coordinates (eg. autopanning)
// but changes in world coordinates (eg. autopanning)
type
==
KiGfx
::
WX_VIEW_CONTROLS
::
EVT_REFRESH_MOUSE
)
type
==
KiGfx
::
WX_VIEW_CONTROLS
::
EVT_REFRESH_MOUSE
)
{
{
VECTOR2D
screenPos
=
m_toolMgr
->
GetViewControls
()
->
GetCursorPosition
();
VECTOR2D
screenPos
=
m_toolMgr
->
GetViewControls
()
->
GetCursorPosition
();
VECTOR2D
pos
=
getView
()
->
ToWorld
(
screenPos
);
VECTOR2D
pos
=
getView
()
->
ToWorld
(
screenPos
);
if
(
pos
!=
m_lastMousePos
||
type
==
KiGfx
::
WX_VIEW_CONTROLS
::
EVT_REFRESH_MOUSE
)
if
(
pos
!=
m_lastMousePos
||
type
==
KiGfx
::
WX_VIEW_CONTROLS
::
EVT_REFRESH_MOUSE
)
{
{
motion
=
true
;
motion
=
true
;
m_lastMousePos
=
pos
;
m_lastMousePos
=
pos
;
}
}
for
(
unsigned
int
i
=
0
;
i
<
m_buttons
.
size
();
i
++
)
for
(
unsigned
int
i
=
0
;
i
<
m_buttons
.
size
();
i
++
)
buttonEvents
|=
handleMouseButton
(
aEvent
,
i
,
motion
);
buttonEvents
|=
handleMouseButton
(
aEvent
,
i
,
motion
);
if
(
!
buttonEvents
&&
motion
)
if
(
!
buttonEvents
&&
motion
)
{
{
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseMotion
);
evt
=
TOOL_EVENT
(
TC_Mouse
,
TA_MouseMotion
);
evt
->
SetMousePosition
(
pos
);
evt
->
SetMousePosition
(
pos
);
}
}
}
}
// Keyboard handling
// Keyboard handling
else
if
(
type
==
wxEVT_KEY_UP
||
type
==
wxEVT_KEY_DOWN
)
else
if
(
type
==
wxEVT_KEY_UP
||
type
==
wxEVT_KEY_DOWN
)
{
{
wxKeyEvent
*
ke
=
static_cast
<
wxKeyEvent
*>
(
&
aEvent
);
wxKeyEvent
*
ke
=
static_cast
<
wxKeyEvent
*>
(
&
aEvent
);
int
key
=
ke
->
GetKeyCode
();
int
key
=
ke
->
GetKeyCode
();
...
@@ -246,33 +246,33 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
...
@@ -246,33 +246,33 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
}
}
}
}
if
(
evt
)
if
(
evt
)
m_toolMgr
->
ProcessEvent
(
*
evt
);
m_toolMgr
->
ProcessEvent
(
*
evt
);
// pass the event to the GUI, it might still be interested in it
// pass the event to the GUI, it might still be interested in it
aEvent
.
Skip
();
aEvent
.
Skip
();
}
}
void
TOOL_DISPATCHER
::
DispatchWxCommand
(
const
wxCommandEvent
&
aEvent
)
void
TOOL_DISPATCHER
::
DispatchWxCommand
(
const
wxCommandEvent
&
aEvent
)
{
{
bool
activateTool
=
false
;
bool
activateTool
=
false
;
std
::
string
toolName
;
std
::
string
toolName
;
// fixme: use TOOL_ACTIONs here
// fixme: use TOOL_ACTIONs here
switch
(
aEvent
.
GetId
()
)
switch
(
aEvent
.
GetId
()
)
{
{
case
ID_PNS_ROUTER_TOOL
:
case
ID_PNS_ROUTER_TOOL
:
toolName
=
"pcbnew.InteractiveRouter"
;
toolName
=
"pcbnew.InteractiveRouter"
;
activateTool
=
true
;
activateTool
=
true
;
break
;
break
;
case
ID_SELECTION_TOOL
:
case
ID_SELECTION_TOOL
:
toolName
=
"pcbnew.InteractiveSelection"
;
toolName
=
"pcbnew.InteractiveSelection"
;
activateTool
=
true
;
activateTool
=
true
;
break
;
break
;
}
}
// do nothing if the legacy view is active
// do nothing if the legacy view is active
if
(
activateTool
&&
m_editFrame
->
IsGalCanvasActive
()
)
if
(
activateTool
&&
m_editFrame
->
IsGalCanvasActive
()
)
m_toolMgr
->
InvokeTool
(
toolName
);
m_toolMgr
->
InvokeTool
(
toolName
);
}
}
common/tool/tool_event.cpp
View file @
22045b61
...
@@ -35,22 +35,22 @@ using namespace std;
...
@@ -35,22 +35,22 @@ using namespace std;
struct
FlagString
struct
FlagString
{
{
int
flag
;
int
flag
;
std
::
string
str
;
std
::
string
str
;
};
};
static
const
std
::
string
flag2string
(
int
flag
,
const
FlagString
*
exps
)
static
const
std
::
string
flag2string
(
int
flag
,
const
FlagString
*
exps
)
{
{
std
::
string
rv
;
std
::
string
rv
;
for
(
int
i
=
0
;
exps
[
i
].
str
.
length
();
i
++
)
for
(
int
i
=
0
;
exps
[
i
].
str
.
length
();
i
++
)
{
{
if
(
exps
[
i
].
flag
&
flag
)
if
(
exps
[
i
].
flag
&
flag
)
rv
+=
exps
[
i
].
str
+
" "
;
rv
+=
exps
[
i
].
str
+
" "
;
}
}
return
rv
;
return
rv
;
}
}
...
@@ -62,97 +62,97 @@ bool TOOL_EVENT::IsAction( const TOOL_ACTION* aAction ) const
...
@@ -62,97 +62,97 @@ bool TOOL_EVENT::IsAction( const TOOL_ACTION* aAction ) const
const
std
::
string
TOOL_EVENT
::
Format
()
const
const
std
::
string
TOOL_EVENT
::
Format
()
const
{
{
std
::
string
ev
;
std
::
string
ev
;
const
FlagString
categories
[]
=
{
const
FlagString
categories
[]
=
{
{
TC_Mouse
,
"mouse"
},
{
TC_Mouse
,
"mouse"
},
{
TC_Keyboard
,
"keyboard"
},
{
TC_Keyboard
,
"keyboard"
},
{
TC_Command
,
"command"
},
{
TC_Command
,
"command"
},
{
TC_Message
,
"message"
},
{
TC_Message
,
"message"
},
{
TC_View
,
"view"
},
{
TC_View
,
"view"
},
{
0
,
""
}
{
0
,
""
}
};
};
const
FlagString
actions
[]
=
{
const
FlagString
actions
[]
=
{
{
TA_MouseClick
,
"click"
},
{
TA_MouseClick
,
"click"
},
{
TA_MouseUp
,
"button-up"
},
{
TA_MouseUp
,
"button-up"
},
{
TA_MouseDown
,
"button-down"
},
{
TA_MouseDown
,
"button-down"
},
{
TA_MouseDrag
,
"drag"
},
{
TA_MouseDrag
,
"drag"
},
{
TA_MouseMotion
,
"motion"
},
{
TA_MouseMotion
,
"motion"
},
{
TA_MouseWheel
,
"wheel"
},
{
TA_MouseWheel
,
"wheel"
},
{
TA_KeyUp
,
"key-up"
},
{
TA_KeyUp
,
"key-up"
},
{
TA_KeyDown
,
"key-down"
},
{
TA_KeyDown
,
"key-down"
},
{
TA_ViewRefresh
,
"view-refresh"
},
{
TA_ViewRefresh
,
"view-refresh"
},
{
TA_ViewZoom
,
"view-zoom"
},
{
TA_ViewZoom
,
"view-zoom"
},
{
TA_ViewPan
,
"view-pan"
},
{
TA_ViewPan
,
"view-pan"
},
{
TA_ViewDirty
,
"view-dirty"
},
{
TA_ViewDirty
,
"view-dirty"
},
{
TA_ChangeLayer
,
"change-layer"
},
{
TA_ChangeLayer
,
"change-layer"
},
{
TA_CancelTool
,
"cancel-tool"
},
{
TA_CancelTool
,
"cancel-tool"
},
{
TA_ContextMenuUpdate
,
"context-menu-update"
},
{
TA_ContextMenuUpdate
,
"context-menu-update"
},
{
TA_ContextMenuChoice
,
"context-menu-choice"
},
{
TA_ContextMenuChoice
,
"context-menu-choice"
},
{
TA_Action
,
"action"
},
{
TA_Action
,
"action"
},
{
0
,
""
}
{
0
,
""
}
};
};
const
FlagString
buttons
[]
=
{
const
FlagString
buttons
[]
=
{
{
MB_None
,
"none"
},
{
MB_None
,
"none"
},
{
MB_Left
,
"left"
},
{
MB_Left
,
"left"
},
{
MB_Right
,
"right"
},
{
MB_Right
,
"right"
},
{
MB_Middle
,
"middle"
},
{
MB_Middle
,
"middle"
},
{
0
,
""
}
{
0
,
""
}
};
};
const
FlagString
modifiers
[]
=
{
const
FlagString
modifiers
[]
=
{
{
MD_ModShift
,
"shift"
},
{
MD_ModShift
,
"shift"
},
{
MD_ModCtrl
,
"ctrl"
},
{
MD_ModCtrl
,
"ctrl"
},
{
MD_ModAlt
,
"alt"
},
{
MD_ModAlt
,
"alt"
},
{
0
,
""
}
{
0
,
""
}
};
};
ev
=
"category: "
;
ev
=
"category: "
;
ev
+=
flag2string
(
m_category
,
categories
);
ev
+=
flag2string
(
m_category
,
categories
);
ev
+=
" action: "
;
ev
+=
" action: "
;
ev
+=
flag2string
(
m_actions
,
actions
);
ev
+=
flag2string
(
m_actions
,
actions
);
if
(
m_actions
&
TA_Mouse
)
if
(
m_actions
&
TA_Mouse
)
{
{
ev
+=
" btns: "
;
ev
+=
" btns: "
;
ev
+=
flag2string
(
m_mouseButtons
,
buttons
);
ev
+=
flag2string
(
m_mouseButtons
,
buttons
);
}
}
if
(
m_actions
&
TA_Keyboard
)
if
(
m_actions
&
TA_Keyboard
)
{
{
char
tmp
[
128
];
char
tmp
[
128
];
sprintf
(
tmp
,
"key: %d"
,
m_keyCode
);
sprintf
(
tmp
,
"key: %d"
,
m_keyCode
);
ev
+=
tmp
;
ev
+=
tmp
;
}
}
if
(
m_actions
&
(
TA_Mouse
|
TA_Keyboard
)
)
if
(
m_actions
&
(
TA_Mouse
|
TA_Keyboard
)
)
{
{
ev
+=
" mods: "
;
ev
+=
" mods: "
;
ev
+=
flag2string
(
m_modifiers
,
modifiers
);
ev
+=
flag2string
(
m_modifiers
,
modifiers
);
}
}
if
(
m_commandId
)
if
(
m_commandId
)
{
{
char
tmp
[
128
];
char
tmp
[
128
];
sprintf
(
tmp
,
"cmd-id: %d"
,
*
m_commandId
);
sprintf
(
tmp
,
"cmd-id: %d"
,
*
m_commandId
);
ev
+=
tmp
;
ev
+=
tmp
;
}
}
if
(
m_commandStr
)
if
(
m_commandStr
)
ev
+=
"cmd-str: "
+
(
*
m_commandStr
);
ev
+=
"cmd-str: "
+
(
*
m_commandStr
);
return
ev
;
return
ev
;
}
}
const
std
::
string
TOOL_EVENT_LIST
::
Format
()
const
const
std
::
string
TOOL_EVENT_LIST
::
Format
()
const
{
{
string
s
;
string
s
;
BOOST_FOREACH
(
TOOL_EVENT
e
,
m_events
)
s
+=
e
.
Format
()
+
" "
;
BOOST_FOREACH
(
TOOL_EVENT
e
,
m_events
)
return
s
;
s
+=
e
.
Format
()
+
" "
;
return
s
;
}
}
common/tool/tool_interactive.cpp
View file @
22045b61
...
@@ -30,13 +30,13 @@
...
@@ -30,13 +30,13 @@
#include <tool/context_menu.h>
#include <tool/context_menu.h>
TOOL_INTERACTIVE
::
TOOL_INTERACTIVE
(
TOOL_ID
aId
,
const
std
::
string
&
aName
)
:
TOOL_INTERACTIVE
::
TOOL_INTERACTIVE
(
TOOL_ID
aId
,
const
std
::
string
&
aName
)
:
TOOL_BASE
(
TOOL_Interactive
,
aId
,
aName
)
TOOL_BASE
(
TOOL_Interactive
,
aId
,
aName
)
{};
{};
TOOL_INTERACTIVE
::
TOOL_INTERACTIVE
(
const
std
::
string
&
aName
)
:
TOOL_INTERACTIVE
::
TOOL_INTERACTIVE
(
const
std
::
string
&
aName
)
:
TOOL_BASE
(
TOOL_Interactive
,
TOOL_MANAGER
::
MakeToolId
(
aName
),
aName
)
TOOL_BASE
(
TOOL_Interactive
,
TOOL_MANAGER
::
MakeToolId
(
aName
),
aName
)
{};
{};
TOOL_INTERACTIVE
::~
TOOL_INTERACTIVE
()
TOOL_INTERACTIVE
::~
TOOL_INTERACTIVE
()
...
@@ -46,18 +46,18 @@ TOOL_INTERACTIVE::~TOOL_INTERACTIVE()
...
@@ -46,18 +46,18 @@ TOOL_INTERACTIVE::~TOOL_INTERACTIVE()
OPT_TOOL_EVENT
TOOL_INTERACTIVE
::
Wait
(
const
TOOL_EVENT_LIST
&
aEventList
)
OPT_TOOL_EVENT
TOOL_INTERACTIVE
::
Wait
(
const
TOOL_EVENT_LIST
&
aEventList
)
{
{
return
m_toolMgr
->
ScheduleWait
(
this
,
aEventList
);
return
m_toolMgr
->
ScheduleWait
(
this
,
aEventList
);
}
}
void
TOOL_INTERACTIVE
::
goInternal
(
TOOL_STATE_FUNC
&
aState
,
const
TOOL_EVENT_LIST
&
aConditions
)
void
TOOL_INTERACTIVE
::
goInternal
(
TOOL_STATE_FUNC
&
aState
,
const
TOOL_EVENT_LIST
&
aConditions
)
{
{
m_toolMgr
->
ScheduleNextState
(
this
,
aState
,
aConditions
);
m_toolMgr
->
ScheduleNextState
(
this
,
aState
,
aConditions
);
}
}
void
TOOL_INTERACTIVE
::
SetContextMenu
(
CONTEXT_MENU
*
aMenu
,
CONTEXT_MENU_TRIGGER
aTrigger
)
void
TOOL_INTERACTIVE
::
SetContextMenu
(
CONTEXT_MENU
*
aMenu
,
CONTEXT_MENU_TRIGGER
aTrigger
)
{
{
aMenu
->
setTool
(
this
);
aMenu
->
setTool
(
this
);
m_toolMgr
->
ScheduleContextMenu
(
this
,
aMenu
,
aTrigger
);
m_toolMgr
->
ScheduleContextMenu
(
this
,
aMenu
,
aTrigger
);
}
}
common/tool/tool_manager.cpp
View file @
22045b61
...
@@ -52,50 +52,50 @@ using namespace std;
...
@@ -52,50 +52,50 @@ using namespace std;
struct
TOOL_MANAGER
::
TOOL_STATE
struct
TOOL_MANAGER
::
TOOL_STATE
{
{
/// The tool itself
/// The tool itself
TOOL_BASE
*
theTool
;
TOOL_BASE
*
theTool
;
/// Is the tool active (pending execution) or disabled at the moment
bool
idle
;
/// Flag defining if the tool is waiting for any event (i.e. if it
/// Is the tool active (pending execution) or disabled at the moment
/// issued a Wait() call).
bool
idle
;
bool
pendingWait
;
/// Is there a context menu being displayed
/// Flag defining if the tool is waiting for any event (i.e. if it
bool
pendingContextMenu
;
/// issued a Wait() call).
bool
pendingWait
;
/// Context menu currently used by the tool
/// Is there a context menu being displayed
CONTEXT_MENU
*
c
ontextMenu
;
bool
pendingC
ontextMenu
;
/// Defines when the context menu is opened
/// Context menu currently used by the tool
CONTEXT_MENU_TRIGGER
contextMenuTrigger
;
CONTEXT_MENU
*
contextMenu
;
/// Tool execution context
/// Defines when the context menu is opened
COROUTINE
<
int
,
TOOL_EVENT
&>*
cofunc
;
CONTEXT_MENU_TRIGGER
contextMenuTrigger
;
/// The event that triggered the execution/wakeup of the tool after Wait() call
TOOL_EVENT
wakeupEvent
;
/// List of events the tool is currently waiting for
/// Tool execution context
TOOL_EVENT_LIST
waitEvents
;
COROUTINE
<
int
,
TOOL_EVENT
&>*
cofunc
;
/// List of possible transitions (ie. association of events and state handlers that are executed
/// The event that triggered the execution/wakeup of the tool after Wait() call
/// upon the event reception
TOOL_EVENT
wakeupEvent
;
std
::
vector
<
TRANSITION
>
transitions
;
bool
operator
==
(
const
TOOL_MANAGER
::
TOOL_STATE
&
aRhs
)
const
/// List of events the tool is currently waiting for
TOOL_EVENT_LIST
waitEvents
;
/// List of possible transitions (ie. association of events and state handlers that are executed
/// upon the event reception
std
::
vector
<
TRANSITION
>
transitions
;
bool
operator
==
(
const
TOOL_MANAGER
::
TOOL_STATE
&
aRhs
)
const
{
{
return
(
aRhs
.
theTool
==
this
->
theTool
);
return
(
aRhs
.
theTool
==
this
->
theTool
);
}
}
bool
operator
!=
(
const
TOOL_MANAGER
::
TOOL_STATE
&
aRhs
)
const
bool
operator
!=
(
const
TOOL_MANAGER
::
TOOL_STATE
&
aRhs
)
const
{
{
return
(
aRhs
.
theTool
!=
this
->
theTool
);
return
(
aRhs
.
theTool
!=
this
->
theTool
);
}
}
};
};
TOOL_MANAGER
::
TOOL_MANAGER
()
:
TOOL_MANAGER
::
TOOL_MANAGER
()
:
m_model
(
NULL
),
m_view
(
NULL
)
m_model
(
NULL
),
m_view
(
NULL
)
{
{
m_actionMgr
=
new
ACTION_MANAGER
(
this
);
m_actionMgr
=
new
ACTION_MANAGER
(
this
);
...
@@ -119,37 +119,37 @@ TOOL_MANAGER::~TOOL_MANAGER()
...
@@ -119,37 +119,37 @@ TOOL_MANAGER::~TOOL_MANAGER()
void
TOOL_MANAGER
::
RegisterTool
(
TOOL_BASE
*
aTool
)
void
TOOL_MANAGER
::
RegisterTool
(
TOOL_BASE
*
aTool
)
{
{
TOOL_STATE
*
st
=
new
TOOL_STATE
;
TOOL_STATE
*
st
=
new
TOOL_STATE
;
st
->
theTool
=
aTool
;
st
->
theTool
=
aTool
;
st
->
idle
=
true
;
st
->
idle
=
true
;
st
->
pendingWait
=
false
;
st
->
pendingWait
=
false
;
st
->
pendingContextMenu
=
false
;
st
->
pendingContextMenu
=
false
;
st
->
cofunc
=
NULL
;
st
->
cofunc
=
NULL
;
st
->
contextMenuTrigger
=
CMENU_OFF
;
st
->
contextMenuTrigger
=
CMENU_OFF
;
m_toolState
[
aTool
]
=
st
;
m_toolState
[
aTool
]
=
st
;
m_toolNameIndex
[
aTool
->
GetName
()]
=
st
;
m_toolNameIndex
[
aTool
->
GetName
()]
=
st
;
m_toolIdIndex
[
aTool
->
GetId
()]
=
st
;
m_toolIdIndex
[
aTool
->
GetId
()]
=
st
;
aTool
->
m_toolMgr
=
this
;
aTool
->
m_toolMgr
=
this
;
if
(
aTool
->
GetType
()
==
TOOL_Interactive
)
if
(
aTool
->
GetType
()
==
TOOL_Interactive
)
{
{
bool
initState
=
static_cast
<
TOOL_INTERACTIVE
*>
(
aTool
)
->
Init
();
bool
initState
=
static_cast
<
TOOL_INTERACTIVE
*>
(
aTool
)
->
Init
();
if
(
!
initState
)
if
(
!
initState
)
{
{
wxLogError
(
wxT
(
"Initialization of the %s tool failed"
),
aTool
->
GetName
().
c_str
()
);
wxLogError
(
wxT
(
"Initialization of the %s tool failed"
),
aTool
->
GetName
().
c_str
()
);
// Unregister the tool
// Unregister the tool
m_toolState
.
erase
(
aTool
);
m_toolState
.
erase
(
aTool
);
m_toolNameIndex
.
erase
(
aTool
->
GetName
()
);
m_toolNameIndex
.
erase
(
aTool
->
GetName
()
);
m_toolIdIndex
.
erase
(
aTool
->
GetId
()
);
m_toolIdIndex
.
erase
(
aTool
->
GetId
()
);
delete
st
;
delete
st
;
delete
aTool
;
delete
aTool
;
}
}
}
}
}
}
...
@@ -268,89 +268,89 @@ TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const
...
@@ -268,89 +268,89 @@ TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const
void
TOOL_MANAGER
::
ScheduleNextState
(
TOOL_BASE
*
aTool
,
TOOL_STATE_FUNC
&
aHandler
,
void
TOOL_MANAGER
::
ScheduleNextState
(
TOOL_BASE
*
aTool
,
TOOL_STATE_FUNC
&
aHandler
,
const
TOOL_EVENT_LIST
&
aConditions
)
const
TOOL_EVENT_LIST
&
aConditions
)
{
{
TOOL_STATE
*
st
=
m_toolState
[
aTool
];
TOOL_STATE
*
st
=
m_toolState
[
aTool
];
st
->
transitions
.
push_back
(
TRANSITION
(
aConditions
,
aHandler
)
);
st
->
transitions
.
push_back
(
TRANSITION
(
aConditions
,
aHandler
)
);
}
}
optional
<
TOOL_EVENT
>
TOOL_MANAGER
::
ScheduleWait
(
TOOL_BASE
*
aTool
,
optional
<
TOOL_EVENT
>
TOOL_MANAGER
::
ScheduleWait
(
TOOL_BASE
*
aTool
,
const
TOOL_EVENT_LIST
&
aConditions
)
const
TOOL_EVENT_LIST
&
aConditions
)
{
{
TOOL_STATE
*
st
=
m_toolState
[
aTool
];
TOOL_STATE
*
st
=
m_toolState
[
aTool
];
// indicate to the manager that we are going to sleep and we shall be
// woken up when an event matching aConditions arrive
st
->
pendingWait
=
true
;
st
->
waitEvents
=
aConditions
;
// switch context back to event dispatcher loop
// indicate to the manager that we are going to sleep and we shall be
st
->
cofunc
->
Yield
();
// woken up when an event matching aConditions arrive
st
->
pendingWait
=
true
;
st
->
waitEvents
=
aConditions
;
return
st
->
wakeupEvent
;
// switch context back to event dispatcher loop
st
->
cofunc
->
Yield
();
return
st
->
wakeupEvent
;
}
}
void
TOOL_MANAGER
::
dispatchInternal
(
TOOL_EVENT
&
aEvent
)
void
TOOL_MANAGER
::
dispatchInternal
(
TOOL_EVENT
&
aEvent
)
{
{
// iterate over all registered tools
// iterate over all registered tools
BOOST_FOREACH
(
TOOL_ID
toolId
,
m_activeTools
)
BOOST_FOREACH
(
TOOL_ID
toolId
,
m_activeTools
)
{
{
TOOL_STATE
*
st
=
m_toolIdIndex
[
toolId
];
TOOL_STATE
*
st
=
m_toolIdIndex
[
toolId
];
// the tool state handler is waiting for events (i.e. called Wait() method)
// the tool state handler is waiting for events (i.e. called Wait() method)
if
(
st
->
pendingWait
)
if
(
st
->
pendingWait
)
{
{
if
(
st
->
waitEvents
.
Matches
(
aEvent
)
)
if
(
st
->
waitEvents
.
Matches
(
aEvent
)
)
{
{
// By default, already processed events are not passed further
// By default, already processed events are not passed further
m_passEvent
=
false
;
m_passEvent
=
false
;
// got matching event? clear wait list and wake up the coroutine
// got matching event? clear wait list and wake up the coroutine
st
->
wakeupEvent
=
aEvent
;
st
->
wakeupEvent
=
aEvent
;
st
->
pendingWait
=
false
;
st
->
pendingWait
=
false
;
st
->
waitEvents
.
clear
();
st
->
waitEvents
.
clear
();
if
(
st
->
cofunc
&&
!
st
->
cofunc
->
Resume
()
)
if
(
st
->
cofunc
&&
!
st
->
cofunc
->
Resume
()
)
finishTool
(
st
);
// The couroutine has finished
finishTool
(
st
);
// The couroutine has finished
// If the tool did not request to propagate
// If the tool did not request to propagate
// the event to other tools, we should stop it now
// the event to other tools, we should stop it now
if
(
!
m_passEvent
)
if
(
!
m_passEvent
)
break
;
break
;
}
}
}
}
}
}
BOOST_FOREACH
(
TOOL_STATE
*
st
,
m_toolState
|
boost
::
adaptors
::
map_values
)
BOOST_FOREACH
(
TOOL_STATE
*
st
,
m_toolState
|
boost
::
adaptors
::
map_values
)
{
{
// the tool scheduled next state(s) by calling Go()
// the tool scheduled next state(s) by calling Go()
if
(
!
st
->
pendingWait
)
if
(
!
st
->
pendingWait
)
{
{
// no state handler in progress - check if there are any transitions (defined by
// no state handler in progress - check if there are any transitions (defined by
// Go() method that match the event.
// Go() method that match the event.
if
(
st
->
transitions
.
size
()
)
if
(
st
->
transitions
.
size
()
)
{
{
BOOST_FOREACH
(
TRANSITION
tr
,
st
->
transitions
)
BOOST_FOREACH
(
TRANSITION
tr
,
st
->
transitions
)
{
{
if
(
tr
.
first
.
Matches
(
aEvent
)
)
if
(
tr
.
first
.
Matches
(
aEvent
)
)
{
{
st
->
transitions
.
clear
();
st
->
transitions
.
clear
();
// no tool context allocated yet? Create one.
// no tool context allocated yet? Create one.
if
(
!
st
->
cofunc
)
if
(
!
st
->
cofunc
)
st
->
cofunc
=
new
COROUTINE
<
int
,
TOOL_EVENT
&>
(
tr
.
second
);
st
->
cofunc
=
new
COROUTINE
<
int
,
TOOL_EVENT
&>
(
tr
.
second
);
else
else
st
->
cofunc
->
SetEntry
(
tr
.
second
);
st
->
cofunc
->
SetEntry
(
tr
.
second
);
// got match? Run the handler.
// got match? Run the handler.
st
->
cofunc
->
Call
(
aEvent
);
st
->
cofunc
->
Call
(
aEvent
);
if
(
!
st
->
cofunc
->
Running
()
)
if
(
!
st
->
cofunc
->
Running
()
)
finishTool
(
st
);
// The couroutine has finished immediately?
finishTool
(
st
);
// The couroutine has finished immediately?
}
}
}
}
}
}
}
}
}
}
}
}
...
@@ -411,90 +411,90 @@ void TOOL_MANAGER::finishTool( TOOL_STATE* aState )
...
@@ -411,90 +411,90 @@ void TOOL_MANAGER::finishTool( TOOL_STATE* aState )
bool
TOOL_MANAGER
::
ProcessEvent
(
TOOL_EVENT
&
aEvent
)
bool
TOOL_MANAGER
::
ProcessEvent
(
TOOL_EVENT
&
aEvent
)
{
{
//
wxLogDebug( "event: %s", aEvent.Format().c_str() );
//
wxLogDebug( "event: %s", aEvent.Format().c_str() );
// Early dispatch of events destined for the TOOL_MANAGER
// Early dispatch of events destined for the TOOL_MANAGER
if
(
!
dispatchStandardEvents
(
aEvent
)
)
if
(
!
dispatchStandardEvents
(
aEvent
)
)
return
false
;
return
false
;
dispatchInternal
(
aEvent
);
dispatchInternal
(
aEvent
);
// popup menu handling
// popup menu handling
BOOST_FOREACH
(
TOOL_ID
toolId
,
m_activeTools
)
BOOST_FOREACH
(
TOOL_ID
toolId
,
m_activeTools
)
{
{
TOOL_STATE
*
st
=
m_toolIdIndex
[
toolId
];
TOOL_STATE
*
st
=
m_toolIdIndex
[
toolId
];
// the tool requested a context menu. The menu is activated on RMB click (CMENU_BUTTON mode)
// the tool requested a context menu. The menu is activated on RMB click (CMENU_BUTTON mode)
// or immediately (CMENU_NOW) mode. The latter is used for clarification lists.
// or immediately (CMENU_NOW) mode. The latter is used for clarification lists.
if
(
st
->
contextMenuTrigger
!=
CMENU_OFF
)
if
(
st
->
contextMenuTrigger
!=
CMENU_OFF
)
{
{
if
(
st
->
contextMenuTrigger
==
CMENU_BUTTON
&&
!
aEvent
.
IsClick
(
MB_Right
)
)
if
(
st
->
contextMenuTrigger
==
CMENU_BUTTON
&&
!
aEvent
.
IsClick
(
MB_Right
)
)
break
;
break
;
st
->
pendingWait
=
true
;
st
->
pendingWait
=
true
;
st
->
waitEvents
=
TOOL_EVENT
(
TC_Any
,
TA_Any
);
st
->
waitEvents
=
TOOL_EVENT
(
TC_Any
,
TA_Any
);
if
(
st
->
contextMenuTrigger
==
CMENU_NOW
)
if
(
st
->
contextMenuTrigger
==
CMENU_NOW
)
st
->
contextMenuTrigger
=
CMENU_OFF
;
st
->
contextMenuTrigger
=
CMENU_OFF
;
boost
::
scoped_ptr
<
CONTEXT_MENU
>
menu
(
new
CONTEXT_MENU
(
*
st
->
contextMenu
)
);
boost
::
scoped_ptr
<
CONTEXT_MENU
>
menu
(
new
CONTEXT_MENU
(
*
st
->
contextMenu
)
);
GetEditFrame
()
->
PopupMenu
(
menu
->
GetMenu
()
);
GetEditFrame
()
->
PopupMenu
(
menu
->
GetMenu
()
);
//
//
TOOL_EVENT
evt
(
TC_Command
,
TA_ContextMenuChoice
);
TOOL_EVENT
evt
(
TC_Command
,
TA_ContextMenuChoice
);
dispatchInternal
(
evt
);
dispatchInternal
(
evt
);
break
;
break
;
}
}
}
}
if
(
m_view
->
IsDirty
()
)
if
(
m_view
->
IsDirty
()
)
{
{
PCB_EDIT_FRAME
*
f
=
static_cast
<
PCB_EDIT_FRAME
*>
(
GetEditFrame
()
);
PCB_EDIT_FRAME
*
f
=
static_cast
<
PCB_EDIT_FRAME
*>
(
GetEditFrame
()
);
f
->
GetGalCanvas
()
->
Refresh
();
// fixme: ugly hack, provide a method in TOOL_DISPATCHER.
f
->
GetGalCanvas
()
->
Refresh
();
// fixme: ugly hack, provide a method in TOOL_DISPATCHER.
}
}
return
false
;
return
false
;
}
}
void
TOOL_MANAGER
::
ScheduleContextMenu
(
TOOL_BASE
*
aTool
,
CONTEXT_MENU
*
aMenu
,
void
TOOL_MANAGER
::
ScheduleContextMenu
(
TOOL_BASE
*
aTool
,
CONTEXT_MENU
*
aMenu
,
CONTEXT_MENU_TRIGGER
aTrigger
)
CONTEXT_MENU_TRIGGER
aTrigger
)
{
{
TOOL_STATE
*
st
=
m_toolState
[
aTool
];
TOOL_STATE
*
st
=
m_toolState
[
aTool
];
st
->
contextMenu
=
aMenu
;
st
->
contextMenu
=
aMenu
;
st
->
contextMenuTrigger
=
aTrigger
;
st
->
contextMenuTrigger
=
aTrigger
;
// the tool wants the menu immediately? Preempt it and do so :)
// the tool wants the menu immediately? Preempt it and do so :)
if
(
aTrigger
==
CMENU_NOW
)
if
(
aTrigger
==
CMENU_NOW
)
st
->
cofunc
->
Yield
();
st
->
cofunc
->
Yield
();
}
}
TOOL_ID
TOOL_MANAGER
::
MakeToolId
(
const
std
::
string
&
aToolName
)
TOOL_ID
TOOL_MANAGER
::
MakeToolId
(
const
std
::
string
&
aToolName
)
{
{
static
int
currentId
;
static
int
currentId
;
return
currentId
++
;
return
currentId
++
;
}
}
void
TOOL_MANAGER
::
SetEnvironment
(
EDA_ITEM
*
aModel
,
KiGfx
::
VIEW
*
aView
,
void
TOOL_MANAGER
::
SetEnvironment
(
EDA_ITEM
*
aModel
,
KiGfx
::
VIEW
*
aView
,
KiGfx
::
VIEW_CONTROLS
*
aViewControls
,
wxWindow
*
aFrame
)
KiGfx
::
VIEW_CONTROLS
*
aViewControls
,
wxWindow
*
aFrame
)
{
{
m_model
=
aModel
;
m_model
=
aModel
;
m_view
=
aView
;
m_view
=
aView
;
m_viewControls
=
aViewControls
;
m_viewControls
=
aViewControls
;
m_editFrame
=
aFrame
;
m_editFrame
=
aFrame
;
// Reset state of the registered tools
// Reset state of the registered tools
BOOST_FOREACH
(
TOOL_ID
toolId
,
m_activeTools
)
BOOST_FOREACH
(
TOOL_ID
toolId
,
m_activeTools
)
{
{
TOOL_BASE
*
tool
=
m_toolIdIndex
[
toolId
]
->
theTool
;
TOOL_BASE
*
tool
=
m_toolIdIndex
[
toolId
]
->
theTool
;
if
(
tool
->
GetType
()
==
TOOL_Interactive
)
if
(
tool
->
GetType
()
==
TOOL_Interactive
)
static_cast
<
TOOL_INTERACTIVE
*>
(
tool
)
->
Reset
();
static_cast
<
TOOL_INTERACTIVE
*>
(
tool
)
->
Reset
();
}
}
}
}
...
...
include/class_drawpanel_gal.h
View file @
22045b61
...
@@ -87,7 +87,7 @@ public:
...
@@ -87,7 +87,7 @@ public:
{
{
return
m_view
;
return
m_view
;
}
}
/**
/**
* Function GetViewControls()
* Function GetViewControls()
* Returns a pointer to the VIEW_CONTROLS instance used in the panel.
* Returns a pointer to the VIEW_CONTROLS instance used in the panel.
...
...
include/gal/color4d.h
View file @
22045b61
...
@@ -131,7 +131,7 @@ public:
...
@@ -131,7 +131,7 @@ public:
* Saturates the color to a given factor (in HSV model)
* Saturates the color to a given factor (in HSV model)
*/
*/
COLOR4D
&
Saturate
(
double
aFactor
);
COLOR4D
&
Saturate
(
double
aFactor
);
/**
/**
* Function Brightened
* Function Brightened
* Returns a color that is brighter by a given factor, without modifying object.
* Returns a color that is brighter by a given factor, without modifying object.
...
...
include/gal/opengl/shader.h
View file @
22045b61
...
@@ -172,11 +172,11 @@ private:
...
@@ -172,11 +172,11 @@ private:
void
programInfo
(
GLuint
aProgram
);
void
programInfo
(
GLuint
aProgram
);
/**
/**
* @brief Get the shader information.
* @brief Get the shader information.
*
*
* @param aShader is the shader number.
* @param aShader is the shader number.
*/
*/
void
shaderInfo
(
GLuint
aShader
);
void
shaderInfo
(
GLuint
aShader
);
/**
/**
* @brief Read the shader source file
* @brief Read the shader source file
...
...
include/geometry/seg.h
View file @
22045b61
...
@@ -36,278 +36,278 @@ typedef boost::optional<VECTOR2I> OPT_VECTOR2I;
...
@@ -36,278 +36,278 @@ typedef boost::optional<VECTOR2I> OPT_VECTOR2I;
class
SEG
class
SEG
{
{
private
:
private
:
typedef
VECTOR2I
::
extended_type
ecoord
;
typedef
VECTOR2I
::
extended_type
ecoord
;
public
:
public
:
friend
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
aStream
,
const
SEG
&
aSeg
);
friend
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
aStream
,
const
SEG
&
aSeg
);
/* Start and the of the segment. Public, to make access simpler. These are references
/* Start and the of the segment. Public, to make access simpler. These are references
* to an object the segment belongs to (e.g. a line chain) or references to locally stored points
* to an object the segment belongs to (e.g. a line chain) or references to locally stored points
* (m_a, m_b).
* (m_a, m_b).
*/
*/
VECTOR2I
&
a
,
b
;
VECTOR2I
&
a
,
b
;
/** Default constructor
/** Default constructor
* Creates an empty (0, 0) segment, locally-referenced
* Creates an empty (0, 0) segment, locally-referenced
*/
*/
SEG
()
:
a
(
m_a
),
b
(
m_b
)
SEG
()
:
a
(
m_a
),
b
(
m_b
)
{
{
a
=
m_a
;
a
=
m_a
;
b
=
m_b
;
b
=
m_b
;
m_is_local
=
true
;
m_is_local
=
true
;
m_index
=
-
1
;
m_index
=
-
1
;
}
}
/**
/**
* Constructor
* Constructor
* Creates a segment between (aX1, aY1) and (aX2, aY2), locally referenced
* Creates a segment between (aX1, aY1) and (aX2, aY2), locally referenced
*/
*/
SEG
(
int
aX1
,
int
aY1
,
int
aX2
,
int
aY2
)
:
a
(
m_a
),
b
(
m_b
)
SEG
(
int
aX1
,
int
aY1
,
int
aX2
,
int
aY2
)
:
a
(
m_a
),
b
(
m_b
)
{
{
m_a
=
VECTOR2I
(
aX1
,
aY1
);
m_a
=
VECTOR2I
(
aX1
,
aY1
);
m_b
=
VECTOR2I
(
aX2
,
aY2
);
m_b
=
VECTOR2I
(
aX2
,
aY2
);
a
=
m_a
;
a
=
m_a
;
b
=
m_b
;
b
=
m_b
;
m_is_local
=
true
;
m_is_local
=
true
;
m_index
=
-
1
;
m_index
=
-
1
;
}
}
/**
/**
* Constructor
* Constructor
* Creates a segment between (aA) and (aB), locally referenced
* Creates a segment between (aA) and (aB), locally referenced
*/
*/
SEG
(
const
VECTOR2I
&
aA
,
const
VECTOR2I
&
aB
)
:
a
(
m_a
),
b
(
m_b
),
m_a
(
aA
),
m_b
(
aB
)
SEG
(
const
VECTOR2I
&
aA
,
const
VECTOR2I
&
aB
)
:
a
(
m_a
),
b
(
m_b
),
m_a
(
aA
),
m_b
(
aB
)
{
{
a
=
m_a
;
a
=
m_a
;
b
=
m_b
;
b
=
m_b
;
m_is_local
=
true
;
m_is_local
=
true
;
m_index
=
-
1
;
m_index
=
-
1
;
}
}
/**
/**
* Constructor
* Constructor
* Creates a segment between (aA) and (aB), referenced to a multi-segment shape
* Creates a segment between (aA) and (aB), referenced to a multi-segment shape
* @param aA reference to the start point in the parent shape
* @param aA reference to the start point in the parent shape
* @param aB reference to the end point in the parent shape
* @param aB reference to the end point in the parent shape
* @param aIndex index of the segment within the parent shape
* @param aIndex index of the segment within the parent shape
*/
*/
SEG
(
VECTOR2I
&
aA
,
VECTOR2I
&
aB
,
int
aIndex
)
:
a
(
aA
),
b
(
aB
)
SEG
(
VECTOR2I
&
aA
,
VECTOR2I
&
aB
,
int
aIndex
)
:
a
(
aA
),
b
(
aB
)
{
{
m_is_local
=
false
;
m_is_local
=
false
;
m_index
=
aIndex
;
m_index
=
aIndex
;
}
}
/**
/**
* Copy constructor
* Copy constructor
*/
*/
SEG
(
const
SEG
&
aSeg
)
:
a
(
m_a
),
b
(
m_b
)
SEG
(
const
SEG
&
aSeg
)
:
a
(
m_a
),
b
(
m_b
)
{
{
if
(
aSeg
.
m_is_local
)
if
(
aSeg
.
m_is_local
)
{
{
m_a
=
aSeg
.
m_a
;
m_a
=
aSeg
.
m_a
;
m_b
=
aSeg
.
m_b
;
m_b
=
aSeg
.
m_b
;
a
=
m_a
;
a
=
m_a
;
b
=
m_b
;
b
=
m_b
;
m_is_local
=
true
;
m_is_local
=
true
;
m_index
=
-
1
;
m_index
=
-
1
;
}
else
{
}
else
{
a
=
aSeg
.
a
;
a
=
aSeg
.
a
;
b
=
aSeg
.
b
;
b
=
aSeg
.
b
;
m_index
=
aSeg
.
m_index
;
m_index
=
aSeg
.
m_index
;
m_is_local
=
false
;
m_is_local
=
false
;
}
}
}
}
SEG
&
operator
=
(
const
SEG
&
aSeg
)
SEG
&
operator
=
(
const
SEG
&
aSeg
)
{
{
a
=
aSeg
.
a
;
a
=
aSeg
.
a
;
b
=
aSeg
.
b
;
b
=
aSeg
.
b
;
m_a
=
aSeg
.
m_a
;
m_a
=
aSeg
.
m_a
;
m_b
=
aSeg
.
m_b
;
m_b
=
aSeg
.
m_b
;
m_index
=
aSeg
.
m_index
;
m_index
=
aSeg
.
m_index
;
m_is_local
=
aSeg
.
m_is_local
;
m_is_local
=
aSeg
.
m_is_local
;
return
*
this
;
return
*
this
;
}
}
/**
/**
* Function LineProject()
* Function LineProject()
*
*
* Computes the perpendicular projection point of aP on a line passing through
* Computes the perpendicular projection point of aP on a line passing through
* ends of the segment.
* ends of the segment.
* @param aP point to project
* @param aP point to project
* @return projected point
* @return projected point
*/
*/
VECTOR2I
LineProject
(
const
VECTOR2I
&
aP
)
const
;
VECTOR2I
LineProject
(
const
VECTOR2I
&
aP
)
const
;
/**
/**
* Function Side()
* Function Side()
*
*
* Determines on which side of directed line passing via segment ends point aP lies.
* Determines on which side of directed line passing via segment ends point aP lies.
* @param aP point to determine the orientation wrs to self
* @param aP point to determine the orientation wrs to self
* @return: < 0: left, 0 : on the line, > 0 : right
* @return: < 0: left, 0 : on the line, > 0 : right
*/
*/
int
Side
(
const
VECTOR2I
&
aP
)
const
int
Side
(
const
VECTOR2I
&
aP
)
const
{
{
const
ecoord
det
=
(
b
-
a
).
Cross
(
aP
-
a
);
const
ecoord
det
=
(
b
-
a
).
Cross
(
aP
-
a
);
return
det
<
0
?
-
1
:
(
det
>
0
?
1
:
0
);
return
det
<
0
?
-
1
:
(
det
>
0
?
1
:
0
);
}
}
/**
/**
* Function LineDistance()
* Function LineDistance()
*
*
* Returns the closest Euclidean distance between point aP and the line defined by
* Returns the closest Euclidean distance between point aP and the line defined by
* the ends of segment (this).
* the ends of segment (this).
* @param aDetermineSide: when true, the sign of the returned value indicates
* @param aDetermineSide: when true, the sign of the returned value indicates
* the side of the line at which we are (negative = left)
* the side of the line at which we are (negative = left)
* @return the distance
* @return the distance
*/
*/
int
LineDistance
(
const
VECTOR2I
&
aP
,
bool
aDetermineSide
=
false
)
const
;
int
LineDistance
(
const
VECTOR2I
&
aP
,
bool
aDetermineSide
=
false
)
const
;
/**
/**
* Function NearestPoint()
* Function NearestPoint()
*
*
* Computes a point on the segment (this) that is closest to point aP.
* Computes a point on the segment (this) that is closest to point aP.
* @return: nearest point
* @return: nearest point
*/
*/
const
VECTOR2I
NearestPoint
(
const
VECTOR2I
&
aP
)
const
;
const
VECTOR2I
NearestPoint
(
const
VECTOR2I
&
aP
)
const
;
/**
/**
* Function Intersect()
* Function Intersect()
*
*
* Computes intersection point of segment (this) with segment aSeg.
* Computes intersection point of segment (this) with segment aSeg.
* @param aSeg: segment to intersect with
* @param aSeg: segment to intersect with
* @param aIgnoreEndpoints: don't treat corner cases (i.e. end of one segment touching the other)
* @param aIgnoreEndpoints: don't treat corner cases (i.e. end of one segment touching the other)
* as intersections.
* as intersections.
* @param aLines: treat segments as infinite lines
* @param aLines: treat segments as infinite lines
* @return intersection point, if exists
* @return intersection point, if exists
*/
*/
OPT_VECTOR2I
Intersect
(
const
SEG
&
aSeg
,
bool
aIgnoreEndpoints
=
false
,
bool
aLines
=
false
)
const
;
OPT_VECTOR2I
Intersect
(
const
SEG
&
aSeg
,
bool
aIgnoreEndpoints
=
false
,
bool
aLines
=
false
)
const
;
/**
/**
* Function IntersectLines()
* Function IntersectLines()
*
*
* Computes the intersection point of lines passing through ends of (this) and aSeg
* Computes the intersection point of lines passing through ends of (this) and aSeg
* @param aSeg segment defining the line to intersect with
* @param aSeg segment defining the line to intersect with
* @return intersection point, if exists
* @return intersection point, if exists
*/
*/
OPT_VECTOR2I
IntersectLines
(
const
SEG
&
aSeg
)
const
OPT_VECTOR2I
IntersectLines
(
const
SEG
&
aSeg
)
const
{
{
return
Intersect
(
aSeg
,
false
,
true
);
return
Intersect
(
aSeg
,
false
,
true
);
}
}
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
)
const
;
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
)
const
;
/**
/**
* Function Distance()
* Function Distance()
*
*
* Computes minimum Euclidean distance to segment aSeg.
* Computes minimum Euclidean distance to segment aSeg.
* @param aSeg other segment
* @param aSeg other segment
* @return minimum distance
* @return minimum distance
*/
*/
ecoord
SquaredDistance
(
const
SEG
&
aSeg
)
const
;
ecoord
SquaredDistance
(
const
SEG
&
aSeg
)
const
;
int
Distance
(
const
SEG
&
aSeg
)
const
int
Distance
(
const
SEG
&
aSeg
)
const
{
{
return
sqrt
(
SquaredDistance
(
aSeg
)
);
return
sqrt
(
SquaredDistance
(
aSeg
)
);
}
}
/**
/**
* Function Distance()
* Function Distance()
*
*
* Computes minimum Euclidean distance to point aP.
* Computes minimum Euclidean distance to point aP.
* @param aP the point
* @param aP the point
* @return minimum distance
* @return minimum distance
*/
*/
ecoord
SquaredDistance
(
const
VECTOR2I
&
aP
)
const
ecoord
SquaredDistance
(
const
VECTOR2I
&
aP
)
const
{
{
return
(
NearestPoint
(
aP
)
-
aP
).
SquaredEuclideanNorm
();
return
(
NearestPoint
(
aP
)
-
aP
).
SquaredEuclideanNorm
();
}
}
int
Distance
(
const
VECTOR2I
&
aP
)
const
int
Distance
(
const
VECTOR2I
&
aP
)
const
{
{
return
sqrt
(
SquaredDistance
(
aP
)
);
return
sqrt
(
SquaredDistance
(
aP
)
);
}
}
/**
/**
* Function Collinear()
* Function Collinear()
*
*
* Checks if segment aSeg lies on the same line as (this).
* Checks if segment aSeg lies on the same line as (this).
* @param aSeg the segment to chech colinearity with
* @param aSeg the segment to chech colinearity with
* @return true, when segments are collinear.
* @return true, when segments are collinear.
*/
*/
bool
Collinear
(
const
SEG
&
aSeg
)
const
bool
Collinear
(
const
SEG
&
aSeg
)
const
{
{
ecoord
qa1
=
a
.
y
-
b
.
y
;
ecoord
qa1
=
a
.
y
-
b
.
y
;
ecoord
qb1
=
b
.
x
-
a
.
x
;
ecoord
qb1
=
b
.
x
-
a
.
x
;
ecoord
qc1
=
-
qa1
*
a
.
x
-
qb1
*
a
.
y
;
ecoord
qc1
=
-
qa1
*
a
.
x
-
qb1
*
a
.
y
;
ecoord
qa2
=
aSeg
.
a
.
y
-
aSeg
.
b
.
y
;
ecoord
qa2
=
aSeg
.
a
.
y
-
aSeg
.
b
.
y
;
ecoord
qb2
=
aSeg
.
b
.
x
-
aSeg
.
a
.
x
;
ecoord
qb2
=
aSeg
.
b
.
x
-
aSeg
.
a
.
x
;
ecoord
qc2
=
-
qa2
*
aSeg
.
a
.
x
-
qb2
*
aSeg
.
a
.
y
;
ecoord
qc2
=
-
qa2
*
aSeg
.
a
.
x
-
qb2
*
aSeg
.
a
.
y
;
return
(
qa1
==
qa2
)
&&
(
qb1
==
qb2
)
&&
(
qc1
==
qc2
);
return
(
qa1
==
qa2
)
&&
(
qb1
==
qb2
)
&&
(
qc1
==
qc2
);
}
}
/**
/**
* Function Length()
* Function Length()
*
*
* Returns the length (this)
* Returns the length (this)
* @return length
* @return length
*/
*/
int
Length
()
const
int
Length
()
const
{
{
return
(
a
-
b
).
EuclideanNorm
();
return
(
a
-
b
).
EuclideanNorm
();
}
}
ecoord
SquaredLength
()
const
ecoord
SquaredLength
()
const
{
{
return
(
a
-
b
).
SquaredEuclideanNorm
();
return
(
a
-
b
).
SquaredEuclideanNorm
();
}
}
/**
/**
* Function Index()
* Function Index()
*
*
* Return the index of this segment in its parent shape (applicable only to non-local segments)
* Return the index of this segment in its parent shape (applicable only to non-local segments)
* @return index value
* @return index value
*/
*/
int
Index
()
const
int
Index
()
const
{
{
return
m_index
;
return
m_index
;
}
}
bool
Contains
(
const
VECTOR2I
&
aP
)
const
;
bool
Contains
(
const
VECTOR2I
&
aP
)
const
;
bool
PointCloserThan
(
const
VECTOR2I
&
aP
,
int
aDist
)
const
;
bool
PointCloserThan
(
const
VECTOR2I
&
aP
,
int
aDist
)
const
;
//
friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg );
//
friend std::ostream& operator<<( std::ostream& stream, const SEG& aSeg );
private
:
private
:
bool
ccw
(
const
VECTOR2I
&
aA
,
const
VECTOR2I
&
aB
,
const
VECTOR2I
&
aC
)
const
;
bool
ccw
(
const
VECTOR2I
&
aA
,
const
VECTOR2I
&
aB
,
const
VECTOR2I
&
aC
)
const
;
///> locally stored start/end coordinates (used when m_is_local == true)
///> locally stored start/end coordinates (used when m_is_local == true)
VECTOR2I
m_a
,
m_b
;
VECTOR2I
m_a
,
m_b
;
///> index withing the parent shape (used when m_is_local == false)
///> index withing the parent shape (used when m_is_local == false)
int
m_index
;
int
m_index
;
///> locality flag
///> locality flag
bool
m_is_local
;
bool
m_is_local
;
};
};
inline
VECTOR2I
SEG
::
LineProject
(
const
VECTOR2I
&
aP
)
const
inline
VECTOR2I
SEG
::
LineProject
(
const
VECTOR2I
&
aP
)
const
{
{
// fixme: numerical errors for large integers
// fixme: numerical errors for large integers
assert
(
false
);
assert
(
false
);
return
VECTOR2I
(
0
,
0
);
return
VECTOR2I
(
0
,
0
);
}
}
inline
int
SEG
::
LineDistance
(
const
VECTOR2I
&
aP
,
bool
aDetermineSide
)
const
inline
int
SEG
::
LineDistance
(
const
VECTOR2I
&
aP
,
bool
aDetermineSide
)
const
{
{
ecoord
p
=
a
.
y
-
b
.
y
;
ecoord
p
=
a
.
y
-
b
.
y
;
ecoord
q
=
b
.
x
-
a
.
x
;
ecoord
q
=
b
.
x
-
a
.
x
;
ecoord
r
=
-
p
*
a
.
x
-
q
*
a
.
y
;
ecoord
r
=
-
p
*
a
.
x
-
q
*
a
.
y
;
ecoord
dist
=
(
p
*
aP
.
x
+
q
*
aP
.
y
+
r
)
/
sqrt
(
p
*
p
+
q
*
q
);
ecoord
dist
=
(
p
*
aP
.
x
+
q
*
aP
.
y
+
r
)
/
sqrt
(
p
*
p
+
q
*
q
);
...
@@ -321,14 +321,14 @@ inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
...
@@ -321,14 +321,14 @@ inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
if
(
l_squared
==
0
)
if
(
l_squared
==
0
)
return
a
;
return
a
;
ecoord
t
=
d
.
Dot
(
aP
-
a
);
ecoord
t
=
d
.
Dot
(
aP
-
a
);
if
(
t
<
0
)
if
(
t
<
0
)
return
a
;
return
a
;
else
if
(
t
>
l_squared
)
else
if
(
t
>
l_squared
)
return
b
;
return
b
;
int
xp
=
rescale
(
t
,
(
ecoord
)
d
.
x
,
l_squared
);
int
xp
=
rescale
(
t
,
(
ecoord
)
d
.
x
,
l_squared
);
int
yp
=
rescale
(
t
,
(
ecoord
)
d
.
y
,
l_squared
);
int
yp
=
rescale
(
t
,
(
ecoord
)
d
.
y
,
l_squared
);
...
@@ -338,7 +338,7 @@ inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
...
@@ -338,7 +338,7 @@ inline const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
aStream
,
const
SEG
&
aSeg
)
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
aStream
,
const
SEG
&
aSeg
)
{
{
if
(
aSeg
.
m_is_local
)
if
(
aSeg
.
m_is_local
)
aStream
<<
"[ local "
<<
aSeg
.
a
<<
" - "
<<
aSeg
.
b
<<
" ]"
;
aStream
<<
"[ local "
<<
aSeg
.
a
<<
" - "
<<
aSeg
.
b
<<
" ]"
;
return
aStream
;
return
aStream
;
}
}
...
...
include/geometry/shape.h
View file @
22045b61
...
@@ -36,109 +36,109 @@
...
@@ -36,109 +36,109 @@
*/
*/
enum
ShapeType
{
enum
ShapeType
{
SH_RECT
=
0
,
///> axis-aligned rectangle
SH_RECT
=
0
,
///> axis-aligned rectangle
SH_SEGMENT
,
///> line segment
SH_SEGMENT
,
///> line segment
SH_LINE_CHAIN
,
///> line chain (polyline)
SH_LINE_CHAIN
,
///> line chain (polyline)
SH_CIRCLE
///> circle
SH_CIRCLE
///> circle
};
};
/**
/**
* Class SHAPE
* Class SHAPE
*
*
* Represents an abstract shape on 2D plane.
* Represents an abstract shape on 2D plane.
*/
*/
class
SHAPE
{
class
SHAPE
{
protected
:
protected
:
typedef
VECTOR2I
::
extended_type
ecoord
;
typedef
VECTOR2I
::
extended_type
ecoord
;
public
:
public
:
/**
/**
* Constructor
* Constructor
*
*
* Creates an empty shape of type aType
* Creates an empty shape of type aType
*/
*/
SHAPE
(
ShapeType
aType
)
:
m_type
(
aType
)
{
};
SHAPE
(
ShapeType
aType
)
:
m_type
(
aType
)
{
};
// Destructor
// Destructor
virtual
~
SHAPE
()
{};
virtual
~
SHAPE
()
{};
/**
/**
* Function Type()
* Function Type()
*
*
* Returns the type of the shape.
* Returns the type of the shape.
* @retval the type
* @retval the type
*/
*/
ShapeType
Type
()
const
{
return
m_type
;
}
ShapeType
Type
()
const
{
return
m_type
;
}
/**
/**
* Function Clone()
* Function Clone()
*
*
* Returns a dynamically allocated copy of the shape
* Returns a dynamically allocated copy of the shape
* @retval copy of the shape
* @retval copy of the shape
*/
*/
virtual
SHAPE
*
Clone
()
const
{
virtual
SHAPE
*
Clone
()
const
{
assert
(
false
);
assert
(
false
);
return
NULL
;
return
NULL
;
};
};
/**
/**
* Function Collide()
* Function Collide()
*
*
* Checks if the boundary of shape (this) lies closer to the point aP than aClearance, indicating
* Checks if the boundary of shape (this) lies closer to the point aP than aClearance, indicating
* a collision.
* a collision.
* @return true, if there is a collision.
* @return true, if there is a collision.
*/
*/
virtual
bool
Collide
(
const
VECTOR2I
&
aP
,
int
aClearance
=
0
)
const
virtual
bool
Collide
(
const
VECTOR2I
&
aP
,
int
aClearance
=
0
)
const
{
{
return
Collide
(
SEG
(
aP
,
aP
),
aClearance
);
return
Collide
(
SEG
(
aP
,
aP
),
aClearance
);
}
}
/**
/**
* Function Collide()
* Function Collide()
*
*
* Checks if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating
* Checks if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating
* a collision.
* a collision.
* @param aShape shape to check collision against
* @param aShape shape to check collision against
* @param aClearance minimum clearance
* @param aClearance minimum clearance
* @param aMTV minimum translation vector
* @param aMTV minimum translation vector
* @return true, if there is a collision.
* @return true, if there is a collision.
*/
*/
virtual
bool
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
,
VECTOR2I
&
aMTV
)
const
;
virtual
bool
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
,
VECTOR2I
&
aMTV
)
const
;
virtual
bool
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
=
0
)
const
;
virtual
bool
Collide
(
const
SHAPE
*
aShape
,
int
aClerance
=
0
)
const
;
/**
/**
* Function Collide()
* Function Collide()
*
*
* Checks if the boundary of shape (this) lies closer to the segment aSeg than aClearance, indicating
* Checks if the boundary of shape (this) lies closer to the segment aSeg than aClearance, indicating
* a collision.
* a collision.
* @return true, if there is a collision.
* @return true, if there is a collision.
*/
*/
virtual
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
=
0
)
const
=
0
;
virtual
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
=
0
)
const
=
0
;
/**
/**
* Function Collide()
* Function Collide()
*
*
* Computes a bounding box of the shape, with a margin of aClearance
* Computes a bounding box of the shape, with a margin of aClearance
* a collision.
* a collision.
* @aClearance how much the bounding box is expanded wrs to the minimum enclosing rectangle for the shape.
* @aClearance how much the bounding box is expanded wrs to the minimum enclosing rectangle for the shape.
* @return the bounding box.
* @return the bounding box.
*/
*/
virtual
const
BOX2I
BBox
(
int
aClearance
=
0
)
const
=
0
;
virtual
const
BOX2I
BBox
(
int
aClearance
=
0
)
const
=
0
;
/**
/**
* Function Centre()
* Function Centre()
*
*
* Computes a center-of-mass of the shape
* Computes a center-of-mass of the shape
* @return the center-of-mass point
* @return the center-of-mass point
*/
*/
virtual
VECTOR2I
Centre
()
const
virtual
VECTOR2I
Centre
()
const
{
{
return
BBox
(
0
).
Centre
();
// if nothing better is available....
return
BBox
(
0
).
Centre
();
// if nothing better is available....
}
}
private
:
private
:
///> type of our shape
///> type of our shape
ShapeType
m_type
;
ShapeType
m_type
;
};
};
...
...
include/geometry/shape_circle.h
View file @
22045b61
...
@@ -30,48 +30,48 @@
...
@@ -30,48 +30,48 @@
class
SHAPE_CIRCLE
:
public
SHAPE
{
class
SHAPE_CIRCLE
:
public
SHAPE
{
public
:
public
:
SHAPE_CIRCLE
()
:
SHAPE_CIRCLE
()
:
SHAPE
(
SH_CIRCLE
),
m_radius
(
0
)
{};
SHAPE
(
SH_CIRCLE
),
m_radius
(
0
)
{};
SHAPE_CIRCLE
(
const
VECTOR2I
&
aCenter
,
int
aRadius
)
:
SHAPE
(
SH_CIRCLE
),
m_radius
(
aRadius
),
m_center
(
aCenter
)
{};
~
SHAPE_CIRCLE
()
{};
SHAPE_CIRCLE
(
const
VECTOR2I
&
aCenter
,
int
aRadius
)
:
SHAPE
(
SH_CIRCLE
),
m_radius
(
aRadius
),
m_center
(
aCenter
)
{};
const
BOX2I
BBox
(
int
aClearance
=
0
)
const
~
SHAPE_CIRCLE
()
{};
{
const
VECTOR2I
rc
(
m_radius
+
aClearance
,
m_radius
+
aClearance
);
return
BOX2I
(
m_center
-
rc
,
rc
*
2
);
}
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
=
0
)
const
const
BOX2I
BBox
(
int
aClearance
=
0
)
const
{
{
int
rc
=
aClearance
+
m_radius
;
const
VECTOR2I
rc
(
m_radius
+
aClearance
,
m_radius
+
aClearance
)
;
return
aSeg
.
Distance
(
m_center
)
<=
rc
;
return
BOX2I
(
m_center
-
rc
,
rc
*
2
)
;
}
}
void
SetRadius
(
int
aRadius
)
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
=
0
)
const
{
{
m_radius
=
aRadius
;
int
rc
=
aClearance
+
m_radius
;
}
return
aSeg
.
Distance
(
m_center
)
<=
rc
;
}
void
SetCenter
(
const
VECTOR2I
&
aCenter
)
void
SetRadius
(
int
aRadius
)
{
{
m_center
=
aCenter
;
m_radius
=
aRadius
;
}
}
int
GetRadius
()
const
void
SetCenter
(
const
VECTOR2I
&
aCenter
)
{
{
return
m_radius
;
m_center
=
aCenter
;
}
}
const
VECTOR2I
GetCenter
()
const
int
GetRadius
()
const
{
{
return
m_center
;
return
m_radius
;
}
}
const
VECTOR2I
GetCenter
()
const
{
return
m_center
;
}
private
:
private
:
int
m_radius
;
int
m_radius
;
VECTOR2I
m_center
;
VECTOR2I
m_center
;
};
};
#endif
#endif
include/geometry/shape_index.h
View file @
22045b61
...
@@ -276,11 +276,11 @@ class SHAPE_INDEX
...
@@ -276,11 +276,11 @@ class SHAPE_INDEX
{
{
BOX2I
box
=
aShape
->
BBox
();
BOX2I
box
=
aShape
->
BBox
();
box
.
Inflate
(
aMinDistance
);
box
.
Inflate
(
aMinDistance
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
return
this
->
m_tree
->
Search
(
min
,
max
,
aVisitor
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
return
this
->
m_tree
->
Search
(
min
,
max
,
aVisitor
);
}
}
/**
/**
...
...
include/geometry/shape_index_list.h
View file @
22045b61
...
@@ -29,205 +29,205 @@
...
@@ -29,205 +29,205 @@
template
<
class
T
>
const
SHAPE
*
defaultShapeFunctor
(
const
T
aItem
)
template
<
class
T
>
const
SHAPE
*
defaultShapeFunctor
(
const
T
aItem
)
{
{
return
aItem
->
GetShape
();
return
aItem
->
GetShape
();
}
}
template
<
class
T
,
const
SHAPE
*
(
ShapeFunctor
)(
const
T
)
=
defaultShapeFunctor
<
T
>
>
template
<
class
T
,
const
SHAPE
*
(
ShapeFunctor
)(
const
T
)
=
defaultShapeFunctor
<
T
>
>
class
SHAPE_INDEX_LIST
{
class
SHAPE_INDEX_LIST
{
struct
ShapeEntry
{
struct
ShapeEntry
{
ShapeEntry
(
T
aParent
)
ShapeEntry
(
T
aParent
)
{
{
shape
=
ShapeFunctor
(
aParent
);
shape
=
ShapeFunctor
(
aParent
);
bbox
=
shape
->
BBox
(
0
);
bbox
=
shape
->
BBox
(
0
);
parent
=
aParent
;
parent
=
aParent
;
}
}
~
ShapeEntry
()
~
ShapeEntry
()
{
{
}
}
T
parent
;
T
parent
;
const
SHAPE
*
shape
;
const
SHAPE
*
shape
;
BOX2I
bbox
;
BOX2I
bbox
;
};
};
typedef
std
::
vector
<
ShapeEntry
>
ShapeVec
;
typedef
std
::
vector
<
ShapeEntry
>
ShapeVec
;
typedef
typename
std
::
vector
<
ShapeEntry
>::
iterator
ShapeVecIter
;
typedef
typename
std
::
vector
<
ShapeEntry
>::
iterator
ShapeVecIter
;
public
:
public
:
// "Normal" iterator interface, for STL algorithms.
// "Normal" iterator interface, for STL algorithms.
class
iterator
{
class
iterator
{
public
:
public
:
iterator
()
{};
iterator
()
{};
iterator
(
ShapeVecIter
aCurrent
)
iterator
(
ShapeVecIter
aCurrent
)
:
m_current
(
aCurrent
)
{};
:
m_current
(
aCurrent
)
{};
iterator
(
const
iterator
&
aB
)
:
iterator
(
const
iterator
&
aB
)
:
m_current
(
aB
.
m_current
)
{};
m_current
(
aB
.
m_current
)
{};
T
operator
*
()
const
T
operator
*
()
const
{
{
return
(
*
m_current
).
parent
;
return
(
*
m_current
).
parent
;
}
}
void
operator
++
()
void
operator
++
()
{
{
++
m_current
;
++
m_current
;
}
}
iterator
&
operator
++
(
int
aDummy
)
iterator
&
operator
++
(
int
aDummy
)
{
{
++
m_current
;
++
m_current
;
return
*
this
;
return
*
this
;
}
}
bool
operator
==
(
const
iterator
&
aRhs
)
const
bool
operator
==
(
const
iterator
&
aRhs
)
const
{
{
return
m_current
==
aRhs
.
m_current
;
return
m_current
==
aRhs
.
m_current
;
}
}
bool
operator
!=
(
const
iterator
&
aRhs
)
const
bool
operator
!=
(
const
iterator
&
aRhs
)
const
{
{
return
m_current
!=
aRhs
.
m_current
;
return
m_current
!=
aRhs
.
m_current
;
}
}
const
iterator
&
operator
=
(
const
iterator
&
aRhs
)
const
iterator
&
operator
=
(
const
iterator
&
aRhs
)
{
{
m_current
=
aRhs
.
m_current
;
m_current
=
aRhs
.
m_current
;
return
*
this
;
return
*
this
;
}
}
private
:
private
:
ShapeVecIter
m_current
;
ShapeVecIter
m_current
;
};
};
// "Query" iterator, for iterating over a set of spatially matching shapes.
// "Query" iterator, for iterating over a set of spatially matching shapes.
class
query_iterator
{
class
query_iterator
{
public
:
public
:
query_iterator
()
query_iterator
()
{
{
}
}
query_iterator
(
ShapeVecIter
aCurrent
,
ShapeVecIter
aEnd
,
SHAPE
*
aShape
,
query_iterator
(
ShapeVecIter
aCurrent
,
ShapeVecIter
aEnd
,
SHAPE
*
aShape
,
int
aMinDistance
,
bool
aExact
)
:
int
aMinDistance
,
bool
aExact
)
:
m_end
(
aEnd
),
m_end
(
aEnd
),
m_current
(
aCurrent
),
m_current
(
aCurrent
),
m_shape
(
aShape
),
m_shape
(
aShape
),
m_minDistance
(
aMinDistance
),
m_minDistance
(
aMinDistance
),
m_exact
(
aExact
)
m_exact
(
aExact
)
{
{
if
(
aShape
)
if
(
aShape
)
{
{
m_refBBox
=
aShape
->
BBox
();
m_refBBox
=
aShape
->
BBox
();
next
();
next
();
}
}
}
}
query_iterator
(
const
query_iterator
&
aB
)
:
query_iterator
(
const
query_iterator
&
aB
)
:
m_end
(
aB
.
m_end
),
m_end
(
aB
.
m_end
),
m_current
(
aB
.
m_current
),
m_current
(
aB
.
m_current
),
m_shape
(
aB
.
m_shape
),
m_shape
(
aB
.
m_shape
),
m_minDistance
(
aB
.
m_minDistance
),
m_minDistance
(
aB
.
m_minDistance
),
m_exact
(
aB
.
m_exact
),
m_exact
(
aB
.
m_exact
),
m_refBBox
(
aB
.
m_refBBox
)
m_refBBox
(
aB
.
m_refBBox
)
{
{
}
}
T
operator
*
()
const
T
operator
*
()
const
{
{
return
(
*
m_current
).
parent
;
return
(
*
m_current
).
parent
;
}
}
query_iterator
&
operator
++
()
query_iterator
&
operator
++
()
{
{
++
m_current
;
++
m_current
;
next
();
next
();
return
*
this
;
return
*
this
;
}
}
query_iterator
&
operator
++
(
int
aDummy
)
query_iterator
&
operator
++
(
int
aDummy
)
{
{
++
m_current
;
++
m_current
;
next
();
next
();
return
*
this
;
return
*
this
;
}
}
bool
operator
==
(
const
query_iterator
&
aRhs
)
const
bool
operator
==
(
const
query_iterator
&
aRhs
)
const
{
{
return
m_current
==
aRhs
.
m_current
;
return
m_current
==
aRhs
.
m_current
;
}
}
bool
operator
!=
(
const
query_iterator
&
aRhs
)
const
bool
operator
!=
(
const
query_iterator
&
aRhs
)
const
{
{
return
m_current
!=
aRhs
.
m_current
;
return
m_current
!=
aRhs
.
m_current
;
}
}
const
query_iterator
&
operator
=
(
const
query_iterator
&
aRhs
)
const
query_iterator
&
operator
=
(
const
query_iterator
&
aRhs
)
{
{
m_end
=
aRhs
.
m_end
;
m_end
=
aRhs
.
m_end
;
m_current
=
aRhs
.
m_current
;
m_current
=
aRhs
.
m_current
;
m_shape
=
aRhs
.
m_shape
;
m_shape
=
aRhs
.
m_shape
;
m_minDistance
=
aRhs
.
m_minDistance
;
m_minDistance
=
aRhs
.
m_minDistance
;
m_exact
=
aRhs
.
m_exact
;
m_exact
=
aRhs
.
m_exact
;
m_refBBox
=
aRhs
.
m_refBBox
;
m_refBBox
=
aRhs
.
m_refBBox
;
return
*
this
;
return
*
this
;
}
}
private
:
private
:
void
next
()
void
next
()
{
{
while
(
m_current
!=
m_end
)
while
(
m_current
!=
m_end
)
{
{
if
(
m_refBBox
.
Distance
(
m_current
->
bbox
)
<=
m_minDistance
)
if
(
m_refBBox
.
Distance
(
m_current
->
bbox
)
<=
m_minDistance
)
{
{
if
(
!
m_exact
||
m_current
->
shape
->
Collide
(
m_shape
,
m_minDistance
)
)
if
(
!
m_exact
||
m_current
->
shape
->
Collide
(
m_shape
,
m_minDistance
)
)
return
;
return
;
}
}
++
m_current
;
++
m_current
;
}
}
}
}
ShapeVecIter
m_end
;
ShapeVecIter
m_end
;
ShapeVecIter
m_current
;
ShapeVecIter
m_current
;
BOX2I
m_refBBox
;
BOX2I
m_refBBox
;
bool
m_exact
;
bool
m_exact
;
SHAPE
*
m_shape
;
SHAPE
*
m_shape
;
int
m_minDistance
;
int
m_minDistance
;
};
};
void
Add
(
T
aItem
)
void
Add
(
T
aItem
)
{
{
ShapeEntry
s
(
aItem
);
ShapeEntry
s
(
aItem
);
m_shapes
.
push_back
(
s
);
m_shapes
.
push_back
(
s
);
}
}
void
Remove
(
const
T
aItem
)
void
Remove
(
const
T
aItem
)
{
{
ShapeVecIter
i
;
ShapeVecIter
i
;
for
(
i
=
m_shapes
.
begin
();
i
!=
m_shapes
.
end
();
++
i
)
for
(
i
=
m_shapes
.
begin
();
i
!=
m_shapes
.
end
();
++
i
)
{
{
if
(
i
->
parent
==
aItem
)
if
(
i
->
parent
==
aItem
)
break
;
break
;
}
}
if
(
i
==
m_shapes
.
end
()
)
if
(
i
==
m_shapes
.
end
()
)
return
;
return
;
m_shapes
.
erase
(
i
);
m_shapes
.
erase
(
i
);
}
}
int
Size
()
const
int
Size
()
const
{
{
return
m_shapes
.
size
();
return
m_shapes
.
size
();
}
}
template
<
class
Visitor
>
template
<
class
Visitor
>
int
Query
(
const
SHAPE
*
aShape
,
int
aMinDistance
,
Visitor
&
aV
,
bool
aExact
=
true
)
//const
int
Query
(
const
SHAPE
*
aShape
,
int
aMinDistance
,
Visitor
&
aV
,
bool
aExact
=
true
)
//const
{
{
ShapeVecIter
i
;
ShapeVecIter
i
;
...
@@ -251,33 +251,33 @@ public:
...
@@ -251,33 +251,33 @@ public:
return
n
;
return
n
;
}
}
void
Clear
()
void
Clear
()
{
{
m_shapes
.
clear
();
m_shapes
.
clear
();
}
}
query_iterator
qbegin
(
SHAPE
*
aShape
,
int
aMinDistance
,
bool
aExact
)
query_iterator
qbegin
(
SHAPE
*
aShape
,
int
aMinDistance
,
bool
aExact
)
{
{
return
query_iterator
(
m_shapes
.
begin
(),
m_shapes
.
end
(),
aShape
,
aMinDistance
,
aExact
);
return
query_iterator
(
m_shapes
.
begin
(),
m_shapes
.
end
(),
aShape
,
aMinDistance
,
aExact
);
}
}
const
query_iterator
qend
()
const
query_iterator
qend
()
{
{
return
query_iterator
(
m_shapes
.
end
(),
m_shapes
.
end
(),
NULL
,
0
,
false
);
return
query_iterator
(
m_shapes
.
end
(),
m_shapes
.
end
(),
NULL
,
0
,
false
);
}
}
iterator
begin
()
iterator
begin
()
{
{
return
iterator
(
m_shapes
.
begin
()
);
return
iterator
(
m_shapes
.
begin
()
);
}
}
iterator
end
()
iterator
end
()
{
{
return
iterator
(
m_shapes
.
end
()
);
return
iterator
(
m_shapes
.
end
()
);
}
}
private
:
private
:
ShapeVec
m_shapes
;
ShapeVec
m_shapes
;
};
};
#endif
#endif
include/geometry/shape_line_chain.h
View file @
22045b61
...
@@ -38,504 +38,504 @@
...
@@ -38,504 +38,504 @@
* Class SHAPE_LINE_CHAIN
* Class SHAPE_LINE_CHAIN
*
*
* Represents a polyline (an zero-thickness chain of connected line segments).
* Represents a polyline (an zero-thickness chain of connected line segments).
* I purposedly didn't name it "polyline" to avoid confusion with the existing CPolyLine class in pcbnew.
* I purposedly didn't name it "polyline" to avoid confusion with the existing CPolyLine class in pcbnew.
*
*
* SHAPE_LINE_CHAIN class shall not be used for polygons!
* SHAPE_LINE_CHAIN class shall not be used for polygons!
*/
*/
class
SHAPE_LINE_CHAIN
:
public
SHAPE
{
class
SHAPE_LINE_CHAIN
:
public
SHAPE
{
private
:
private
:
typedef
std
::
vector
<
VECTOR2I
>::
iterator
point_iter
;
typedef
std
::
vector
<
VECTOR2I
>::
iterator
point_iter
;
typedef
std
::
vector
<
VECTOR2I
>::
const_iterator
point_citer
;
typedef
std
::
vector
<
VECTOR2I
>::
const_iterator
point_citer
;
public
:
public
:
/**
/**
* Struct Intersection
* Struct Intersection
*
*
* Represents an intersection between two line segments
* Represents an intersection between two line segments
*/
*/
struct
Intersection
struct
Intersection
{
{
/// segment belonging from the (this) argument of Intersect()
/// segment belonging from the (this) argument of Intersect()
SEG
our
;
SEG
our
;
/// segment belonging from the aOther argument of Intersect()
/// segment belonging from the aOther argument of Intersect()
SEG
their
;
SEG
their
;
/// point of intersection between our and their.
/// point of intersection between our and their.
VECTOR2I
p
;
VECTOR2I
p
;
};
};
typedef
std
::
vector
<
Intersection
>
Intersections
;
typedef
std
::
vector
<
Intersection
>
Intersections
;
/**
/**
* Constructor
* Constructor
* Initializes an empty line chain.
* Initializes an empty line chain.
*/
*/
SHAPE_LINE_CHAIN
()
:
SHAPE_LINE_CHAIN
()
:
SHAPE
(
SH_LINE_CHAIN
),
m_closed
(
false
)
{};
SHAPE
(
SH_LINE_CHAIN
),
m_closed
(
false
)
{};
/**
/**
* Copy Constructor
* Copy Constructor
*/
*/
SHAPE_LINE_CHAIN
(
const
SHAPE_LINE_CHAIN
&
aShape
)
:
SHAPE_LINE_CHAIN
(
const
SHAPE_LINE_CHAIN
&
aShape
)
:
SHAPE
(
SH_LINE_CHAIN
),
m_points
(
aShape
.
m_points
),
m_closed
(
aShape
.
m_closed
)
{};
SHAPE
(
SH_LINE_CHAIN
),
m_points
(
aShape
.
m_points
),
m_closed
(
aShape
.
m_closed
)
{};
/**
/**
* Constructor
* Constructor
* Initializes a 2-point line chain (a single segment)
* Initializes a 2-point line chain (a single segment)
*/
*/
SHAPE_LINE_CHAIN
(
const
VECTOR2I
&
aA
,
const
VECTOR2I
&
aB
)
:
SHAPE_LINE_CHAIN
(
const
VECTOR2I
&
aA
,
const
VECTOR2I
&
aB
)
:
SHAPE
(
SH_LINE_CHAIN
),
SHAPE
(
SH_LINE_CHAIN
),
m_closed
(
false
)
m_closed
(
false
)
{
{
m_points
.
resize
(
2
);
m_points
.
resize
(
2
);
m_points
[
0
]
=
aA
;
m_points
[
0
]
=
aA
;
m_points
[
1
]
=
aB
;
m_points
[
1
]
=
aB
;
}
}
SHAPE_LINE_CHAIN
(
const
VECTOR2I
&
aA
,
const
VECTOR2I
&
aB
,
const
VECTOR2I
&
aC
)
:
SHAPE_LINE_CHAIN
(
const
VECTOR2I
&
aA
,
const
VECTOR2I
&
aB
,
const
VECTOR2I
&
aC
)
:
SHAPE
(
SH_LINE_CHAIN
),
SHAPE
(
SH_LINE_CHAIN
),
m_closed
(
false
)
m_closed
(
false
)
{
{
m_points
.
resize
(
3
);
m_points
.
resize
(
3
);
m_points
[
0
]
=
aA
;
m_points
[
0
]
=
aA
;
m_points
[
1
]
=
aB
;
m_points
[
1
]
=
aB
;
m_points
[
2
]
=
aC
;
m_points
[
2
]
=
aC
;
}
}
SHAPE_LINE_CHAIN
(
const
VECTOR2I
*
aV
,
int
aCount
)
:
SHAPE_LINE_CHAIN
(
const
VECTOR2I
*
aV
,
int
aCount
)
:
SHAPE
(
SH_LINE_CHAIN
),
SHAPE
(
SH_LINE_CHAIN
),
m_closed
(
false
)
m_closed
(
false
)
{
{
m_points
.
resize
(
aCount
);
m_points
.
resize
(
aCount
);
for
(
int
i
=
0
;
i
<
aCount
;
i
++
)
for
(
int
i
=
0
;
i
<
aCount
;
i
++
)
m_points
[
i
]
=
*
aV
++
;
m_points
[
i
]
=
*
aV
++
;
}
}
~
SHAPE_LINE_CHAIN
()
{};
~
SHAPE_LINE_CHAIN
()
{};
/**
/**
* Function Clear()
* Function Clear()
* Removes all points from the line chain.
* Removes all points from the line chain.
*/
*/
void
Clear
()
void
Clear
()
{
{
m_points
.
clear
();
m_points
.
clear
();
m_closed
=
false
;
m_closed
=
false
;
}
}
/**
/**
* Function SetClosed()
* Function SetClosed()
*
*
* Marks the line chain as closed (i.e. with a segment connecting the last point with the first point).
* Marks the line chain as closed (i.e. with a segment connecting the last point with the first point).
* @param aClosed: whether the line chain is to be closed or not.
* @param aClosed: whether the line chain is to be closed or not.
*/
*/
void
SetClosed
(
bool
aClosed
)
void
SetClosed
(
bool
aClosed
)
{
{
m_closed
=
aClosed
;
m_closed
=
aClosed
;
}
}
/**
/**
* Function IsClosed()
* Function IsClosed()
*
*
* @return aClosed: true, when our line is closed.
* @return aClosed: true, when our line is closed.
*/
*/
bool
IsClosed
()
const
bool
IsClosed
()
const
{
{
return
m_closed
;
return
m_closed
;
}
}
/**
/**
* Function SegmentCount()
* Function SegmentCount()
*
*
* Returns number of segments in this line chain.
* Returns number of segments in this line chain.
* @return number of segments
* @return number of segments
*/
*/
int
SegmentCount
()
const
int
SegmentCount
()
const
{
{
int
c
=
m_points
.
size
()
-
1
;
int
c
=
m_points
.
size
()
-
1
;
if
(
m_closed
)
if
(
m_closed
)
c
++
;
c
++
;
return
std
::
max
(
0
,
c
);
return
std
::
max
(
0
,
c
);
}
}
/**
/**
* Function PointCount()
* Function PointCount()
*
*
* Returns the number of points (vertices) in this line chain
* Returns the number of points (vertices) in this line chain
* @return number of points
* @return number of points
*/
*/
int
PointCount
()
const
int
PointCount
()
const
{
{
return
m_points
.
size
();
return
m_points
.
size
();
}
}
/**
/**
* Function Segment()
* Function Segment()
*
*
* Returns a segment referencing to the segment (index) in the line chain.
* Returns a segment referencing to the segment (index) in the line chain.
* Modifying ends of the returned segment will modify corresponding points in the line chain.
* Modifying ends of the returned segment will modify corresponding points in the line chain.
* @param aIndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* @param aIndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* the last segment in the line chain)
* the last segment in the line chain)
* @return SEG referenced to given segment in the line chain
* @return SEG referenced to given segment in the line chain
*/
*/
SEG
Segment
(
int
aIndex
)
SEG
Segment
(
int
aIndex
)
{
{
if
(
aIndex
<
0
)
if
(
aIndex
<
0
)
aIndex
+=
SegmentCount
();
aIndex
+=
SegmentCount
();
if
(
aIndex
==
(
m_points
.
size
()
-
1
)
&&
m_closed
)
if
(
aIndex
==
(
m_points
.
size
()
-
1
)
&&
m_closed
)
return
SEG
(
m_points
[
aIndex
],
m_points
[
0
],
aIndex
);
return
SEG
(
m_points
[
aIndex
],
m_points
[
0
],
aIndex
);
else
else
return
SEG
(
m_points
[
aIndex
],
m_points
[
aIndex
+
1
],
aIndex
);
return
SEG
(
m_points
[
aIndex
],
m_points
[
aIndex
+
1
],
aIndex
);
}
}
/**
/**
* Function CSegment()
* Function CSegment()
*
*
* Returns a read-only segment referencing to the segment (index) in the line chain.
* Returns a read-only segment referencing to the segment (index) in the line chain.
* @param aIndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* @param aIndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* the last segment in the line chain)
* the last segment in the line chain)
* @return SEG referenced to given segment in the line chain
* @return SEG referenced to given segment in the line chain
*/
*/
const
SEG
CSegment
(
int
aIndex
)
const
const
SEG
CSegment
(
int
aIndex
)
const
{
{
if
(
aIndex
<
0
)
if
(
aIndex
<
0
)
aIndex
+=
SegmentCount
();
aIndex
+=
SegmentCount
();
if
(
aIndex
==
(
m_points
.
size
()
-
1
)
&&
m_closed
)
if
(
aIndex
==
(
m_points
.
size
()
-
1
)
&&
m_closed
)
return
SEG
(
const_cast
<
VECTOR2I
&>
(
m_points
[
aIndex
]
),
return
SEG
(
const_cast
<
VECTOR2I
&>
(
m_points
[
aIndex
]
),
const_cast
<
VECTOR2I
&>
(
m_points
[
0
]
),
aIndex
);
const_cast
<
VECTOR2I
&>
(
m_points
[
0
]
),
aIndex
);
else
else
return
SEG
(
const_cast
<
VECTOR2I
&>
(
m_points
[
aIndex
]
),
return
SEG
(
const_cast
<
VECTOR2I
&>
(
m_points
[
aIndex
]
),
const_cast
<
VECTOR2I
&>
(
m_points
[
aIndex
+
1
]
),
aIndex
);
const_cast
<
VECTOR2I
&>
(
m_points
[
aIndex
+
1
]
),
aIndex
);
}
}
/**
/**
* Function Point()
* Function Point()
*
*
* Returns a reference to a given point in the line chain.
* Returns a reference to a given point in the line chain.
* @param aIndex index of the point
* @param aIndex index of the point
* @return reference to the point
* @return reference to the point
*/
*/
VECTOR2I
&
Point
(
int
aIndex
)
VECTOR2I
&
Point
(
int
aIndex
)
{
{
if
(
aIndex
<
0
)
if
(
aIndex
<
0
)
aIndex
+=
PointCount
();
aIndex
+=
PointCount
();
return
m_points
[
aIndex
];
return
m_points
[
aIndex
];
}
}
/**
/**
* Function CPoint()
* Function CPoint()
*
*
* Returns a const reference to a given point in the line chain.
* Returns a const reference to a given point in the line chain.
* @param aIndex index of the point
* @param aIndex index of the point
* @return const reference to the point
* @return const reference to the point
*/
*/
const
VECTOR2I
&
CPoint
(
int
aIndex
)
const
const
VECTOR2I
&
CPoint
(
int
aIndex
)
const
{
{
if
(
aIndex
<
0
)
if
(
aIndex
<
0
)
aIndex
+=
PointCount
();
aIndex
+=
PointCount
();
return
m_points
[
aIndex
];
return
m_points
[
aIndex
];
}
}
/// @copydoc SHAPE::BBox()
/// @copydoc SHAPE::BBox()
const
BOX2I
BBox
(
int
aClearance
=
0
)
const
const
BOX2I
BBox
(
int
aClearance
=
0
)
const
{
{
BOX2I
bbox
;
BOX2I
bbox
;
bbox
.
Compute
(
m_points
);
bbox
.
Compute
(
m_points
);
return
bbox
;
return
bbox
;
}
}
/**
/**
* Function Collide()
* Function Collide()
*
*
* Checks if point aP lies closer to us than aClearance.
* Checks if point aP lies closer to us than aClearance.
* @param aP the point to check for collisions with
* @param aP the point to check for collisions with
* @param aClearance minimum distance that does not qualify as a collision.
* @param aClearance minimum distance that does not qualify as a collision.
* @return true, when a collision has been found
* @return true, when a collision has been found
*/
*/
bool
Collide
(
const
VECTOR2I
&
aP
,
int
aClearance
=
0
)
const
;
bool
Collide
(
const
VECTOR2I
&
aP
,
int
aClearance
=
0
)
const
;
/**
/**
* Function Collide()
* Function Collide()
*
*
* Checks if box aBox lies closer to us than aClearance.
* Checks if box aBox lies closer to us than aClearance.
* @param aP the box to check for collisions with
* @param aP the box to check for collisions with
* @param aClearance minimum distance that does not qualify as a collision.
* @param aClearance minimum distance that does not qualify as a collision.
* @return true, when a collision has been found
* @return true, when a collision has been found
*/
*/
bool
Collide
(
const
BOX2I
&
aBox
,
int
aClearance
=
0
)
const
;
bool
Collide
(
const
BOX2I
&
aBox
,
int
aClearance
=
0
)
const
;
/**
/**
* Function Collide()
* Function Collide()
*
*
* Checks if segment aSeg lies closer to us than aClearance.
* Checks if segment aSeg lies closer to us than aClearance.
* @param aSeg the segment to check for collisions with
* @param aSeg the segment to check for collisions with
* @param aClearance minimum distance that does not qualify as a collision.
* @param aClearance minimum distance that does not qualify as a collision.
* @return true, when a collision has been found
* @return true, when a collision has been found
*/
*/
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
=
0
)
const
;
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
=
0
)
const
;
/**
/**
* Function Distance()
* Function Distance()
*
*
* Computes the minimum distance between the line chain and a point aP.
* Computes the minimum distance between the line chain and a point aP.
* @param aP the point
* @param aP the point
* @return minimum distance.
* @return minimum distance.
*/
*/
int
Distance
(
const
VECTOR2I
&
aP
)
const
;
int
Distance
(
const
VECTOR2I
&
aP
)
const
;
/**
/**
* Function Reverse()
* Function Reverse()
*
*
* Reverses point order in the line chain.
* Reverses point order in the line chain.
* @return line chain with reversed point order (original A-B-C-D: returned D-C-B-A)
* @return line chain with reversed point order (original A-B-C-D: returned D-C-B-A)
*/
*/
const
SHAPE_LINE_CHAIN
Reverse
()
const
;
const
SHAPE_LINE_CHAIN
Reverse
()
const
;
/**
/**
* Function Length()
* Function Length()
*
*
* Returns length of the line chain in Euclidean metric.
* Returns length of the line chain in Euclidean metric.
* @return length of the line chain
* @return length of the line chain
*/
*/
int
Length
()
const
;
int
Length
()
const
;
/**
/**
* Function Append()
* Function Append()
*
*
* Appends a new point at the end of the line chain.
* Appends a new point at the end of the line chain.
* @param aX is X coordinate of the new point
* @param aX is X coordinate of the new point
* @param aY is Y coordinate of the new point
* @param aY is Y coordinate of the new point
*/
*/
void
Append
(
int
aX
,
int
aY
)
void
Append
(
int
aX
,
int
aY
)
{
{
VECTOR2I
v
(
aX
,
aY
);
VECTOR2I
v
(
aX
,
aY
);
Append
(
v
);
Append
(
v
);
}
}
/**
/**
* Function Append()
* Function Append()
*
*
* Appends a new point at the end of the line chain.
* Appends a new point at the end of the line chain.
* @param aP the new point
* @param aP the new point
*/
*/
void
Append
(
const
VECTOR2I
&
aP
)
void
Append
(
const
VECTOR2I
&
aP
)
{
{
if
(
m_points
.
size
()
==
0
)
if
(
m_points
.
size
()
==
0
)
m_bbox
=
BOX2I
(
aP
,
VECTOR2I
(
0
,
0
)
);
m_bbox
=
BOX2I
(
aP
,
VECTOR2I
(
0
,
0
)
);
if
(
m_points
.
size
()
==
0
||
CPoint
(
-
1
)
!=
aP
)
if
(
m_points
.
size
()
==
0
||
CPoint
(
-
1
)
!=
aP
)
{
{
m_points
.
push_back
(
aP
);
m_points
.
push_back
(
aP
);
m_bbox
.
Merge
(
aP
);
m_bbox
.
Merge
(
aP
);
}
}
}
}
/**
/**
* Function Append()
* Function Append()
*
*
* Appends another line chain at the end.
* Appends another line chain at the end.
* @param aOtherLine the line chain to be appended.
* @param aOtherLine the line chain to be appended.
*/
*/
void
Append
(
const
SHAPE_LINE_CHAIN
&
aOtherLine
)
void
Append
(
const
SHAPE_LINE_CHAIN
&
aOtherLine
)
{
{
if
(
aOtherLine
.
PointCount
()
==
0
)
if
(
aOtherLine
.
PointCount
()
==
0
)
return
;
return
;
else
if
(
PointCount
()
==
0
||
aOtherLine
.
CPoint
(
0
)
!=
CPoint
(
-
1
)
)
else
if
(
PointCount
()
==
0
||
aOtherLine
.
CPoint
(
0
)
!=
CPoint
(
-
1
)
)
{
{
const
VECTOR2I
p
=
aOtherLine
.
CPoint
(
0
);
const
VECTOR2I
p
=
aOtherLine
.
CPoint
(
0
);
m_points
.
push_back
(
p
);
m_points
.
push_back
(
p
);
m_bbox
.
Merge
(
p
);
m_bbox
.
Merge
(
p
);
}
}
for
(
int
i
=
1
;
i
<
aOtherLine
.
PointCount
();
i
++
)
for
(
int
i
=
1
;
i
<
aOtherLine
.
PointCount
();
i
++
)
{
{
const
VECTOR2I
p
=
aOtherLine
.
CPoint
(
i
);
const
VECTOR2I
p
=
aOtherLine
.
CPoint
(
i
);
m_points
.
push_back
(
p
);
m_points
.
push_back
(
p
);
m_bbox
.
Merge
(
p
);
m_bbox
.
Merge
(
p
);
}
}
}
}
/**
/**
* Function Replace()
* Function Replace()
*
*
* Replaces points with indices in range [start_index, end_index] with a single
* Replaces points with indices in range [start_index, end_index] with a single
* point aP.
* point aP.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aP replacement point
* @param aP replacement point
*/
*/
void
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
VECTOR2I
&
aP
);
void
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
VECTOR2I
&
aP
);
/**
/**
* Function Replace()
* Function Replace()
*
*
* Replaces points with indices in range [start_index, end_index] with the points from
* Replaces points with indices in range [start_index, end_index] with the points from
* line chain aLine.
* line chain aLine.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aLine replacement line chain.
* @param aLine replacement line chain.
*/
*/
void
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
SHAPE_LINE_CHAIN
&
aLine
);
void
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
SHAPE_LINE_CHAIN
&
aLine
);
/**
/**
* Function Remove()
* Function Remove()
*
*
* Removes the range of points [start_index, end_index] from the line chain.
* Removes the range of points [start_index, end_index] from the line chain.
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aStartIndex start of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
* @param aEndIndex end of the point range to be replaced (inclusive)
*/
*/
void
Remove
(
int
aStartIndex
,
int
aEndIndex
);
void
Remove
(
int
aStartIndex
,
int
aEndIndex
);
/**
/**
* Function Split()
* Function Split()
*
*
* Inserts the point aP belonging to one of the our segments, splitting the adjacent
* Inserts the point aP belonging to one of the our segments, splitting the adjacent
* segment in two.
* segment in two.
* @param aP the point to be inserted
* @param aP the point to be inserted
* @return index of the newly inserted point (or a negative value if aP does not lie on our line)
* @return index of the newly inserted point (or a negative value if aP does not lie on our line)
*/
*/
int
Split
(
const
VECTOR2I
&
aP
);
int
Split
(
const
VECTOR2I
&
aP
);
/**
/**
* Function Find()
* Function Find()
*
*
* Searches for point aP.
* Searches for point aP.
* @param aP the point to be looked for
* @param aP the point to be looked for
* @return index of the correspoinding point in the line chain or negative when not found.
* @return index of the correspoinding point in the line chain or negative when not found.
*/
*/
int
Find
(
const
VECTOR2I
&
aP
)
const
;
int
Find
(
const
VECTOR2I
&
aP
)
const
;
/**
/**
* Function Slice()
* Function Slice()
*
*
* Returns a subset of this line chain containing the [start_index, end_index] range of points.
* Returns a subset of this line chain containing the [start_index, end_index] range of points.
* @param aStartIndex start of the point range to be returned (inclusive)
* @param aStartIndex start of the point range to be returned (inclusive)
* @param aEndIndex end of the point range to be returned (inclusive)
* @param aEndIndex end of the point range to be returned (inclusive)
* @return cut line chain.
* @return cut line chain.
*/
*/
const
SHAPE_LINE_CHAIN
Slice
(
int
aStartIndex
,
int
aEndIndex
=
-
1
)
const
;
const
SHAPE_LINE_CHAIN
Slice
(
int
aStartIndex
,
int
aEndIndex
=
-
1
)
const
;
struct
compareOriginDistance
struct
compareOriginDistance
{
{
compareOriginDistance
(
VECTOR2I
&
aOrigin
)
:
compareOriginDistance
(
VECTOR2I
&
aOrigin
)
:
m_origin
(
aOrigin
)
{};
m_origin
(
aOrigin
)
{};
bool
operator
()(
const
Intersection
&
aA
,
const
Intersection
&
aB
)
bool
operator
()(
const
Intersection
&
aA
,
const
Intersection
&
aB
)
{
{
return
(
m_origin
-
aA
.
p
).
EuclideanNorm
()
<
(
m_origin
-
aB
.
p
).
EuclideanNorm
();
return
(
m_origin
-
aA
.
p
).
EuclideanNorm
()
<
(
m_origin
-
aB
.
p
).
EuclideanNorm
();
}
}
VECTOR2I
m_origin
;
VECTOR2I
m_origin
;
};
};
/**
/**
* Function Intersect()
* Function Intersect()
*
*
* Finds all intersection points between our line chain and the segment aSeg.
* Finds all intersection points between our line chain and the segment aSeg.
* @param aSeg the segment chain to find intersections with
* @param aSeg the segment chain to find intersections with
* @param aIp reference to a vector to store found intersections. Intersection points
* @param aIp reference to a vector to store found intersections. Intersection points
* are sorted with increasing distances from point aSeg.a.
* are sorted with increasing distances from point aSeg.a.
* @return number of intersections found
* @return number of intersections found
*/
*/
int
Intersect
(
const
SEG
&
aSeg
,
Intersections
&
aIp
)
const
;
int
Intersect
(
const
SEG
&
aSeg
,
Intersections
&
aIp
)
const
;
/**
/**
* Function Intersect()
* Function Intersect()
*
*
* Finds all intersection points between our line chain and the line chain aChain.
* Finds all intersection points between our line chain and the line chain aChain.
* @param aChain the line chain to find intersections with
* @param aChain the line chain to find intersections with
* @param aIp reference to a vector to store found intersections. Intersection points
* @param aIp reference to a vector to store found intersections. Intersection points
* are sorted with increasing path lengths from the starting point of aChain.
* are sorted with increasing path lengths from the starting point of aChain.
* @return number of intersections found
* @return number of intersections found
*/
*/
int
Intersect
(
const
SHAPE_LINE_CHAIN
&
aChain
,
Intersections
&
aIp
)
const
;
int
Intersect
(
const
SHAPE_LINE_CHAIN
&
aChain
,
Intersections
&
aIp
)
const
;
/**
/**
* Function PathLength()
* Function PathLength()
*
*
* Computes the walk path length from the beginning of the line chain and
* Computes the walk path length from the beginning of the line chain and
* the point aP belonging to our line.
* the point aP belonging to our line.
* @return: path length in Euclidean metric or negative if aP does not belong to the line chain.
* @return: path length in Euclidean metric or negative if aP does not belong to the line chain.
*/
*/
int
PathLength
(
const
VECTOR2I
&
aP
)
const
;
int
PathLength
(
const
VECTOR2I
&
aP
)
const
;
/**
/**
* Function PointInside()
* Function PointInside()
*
*
* Checks if point aP lies inside a convex polygon defined by the line chain. For closed
* Checks if point aP lies inside a convex polygon defined by the line chain. For closed
* shapes only.
* shapes only.
* @param aP point to check
* @param aP point to check
* @return true if the point is inside the shape (edge is not treated as being inside).
* @return true if the point is inside the shape (edge is not treated as being inside).
*/
*/
bool
PointInside
(
const
VECTOR2I
&
aP
)
const
;
bool
PointInside
(
const
VECTOR2I
&
aP
)
const
;
/**
/**
* Function PointOnEdge()
* Function PointOnEdge()
*
*
* Checks if point aP lies on an edge or vertex of the line chain.
* Checks if point aP lies on an edge or vertex of the line chain.
* @param aP point to check
* @param aP point to check
* @return true if the point lies on the edge.
* @return true if the point lies on the edge.
*/
*/
bool
PointOnEdge
(
const
VECTOR2I
&
aP
)
const
;
bool
PointOnEdge
(
const
VECTOR2I
&
aP
)
const
;
/**
/**
* Function SelfIntersecting()
* Function SelfIntersecting()
*
*
* Checks if the line chain is self-intersecting.
* Checks if the line chain is self-intersecting.
* @return (optional) first found self-intersection point.
* @return (optional) first found self-intersection point.
*/
*/
const
boost
::
optional
<
Intersection
>
SelfIntersecting
()
const
;
const
boost
::
optional
<
Intersection
>
SelfIntersecting
()
const
;
/**
/**
* Function Simplify()
* Function Simplify()
*
*
* Simplifies the line chain by removing colinear adjacent segments and duplicate vertices.
* Simplifies the line chain by removing colinear adjacent segments and duplicate vertices.
* @return reference to self.
* @return reference to self.
*/
*/
SHAPE_LINE_CHAIN
&
Simplify
();
SHAPE_LINE_CHAIN
&
Simplify
();
/**
/**
* Function NearestPoint()
* Function NearestPoint()
*
*
* Finds a point on the line chain that is closest to point aP.
* Finds a point on the line chain that is closest to point aP.
* @return the nearest point.
* @return the nearest point.
*/
*/
const
VECTOR2I
NearestPoint
(
const
VECTOR2I
&
aP
)
const
;
const
VECTOR2I
NearestPoint
(
const
VECTOR2I
&
aP
)
const
;
/// @copydoc SHAPE::Format()
/// @copydoc SHAPE::Format()
const
std
::
string
Format
()
const
;
const
std
::
string
Format
()
const
;
bool
operator
!=
(
const
SHAPE_LINE_CHAIN
&
aRhs
)
const
bool
operator
!=
(
const
SHAPE_LINE_CHAIN
&
aRhs
)
const
{
{
if
(
PointCount
()
!=
aRhs
.
PointCount
()
)
if
(
PointCount
()
!=
aRhs
.
PointCount
()
)
return
true
;
return
true
;
for
(
int
i
=
0
;
i
<
PointCount
();
i
++
)
for
(
int
i
=
0
;
i
<
PointCount
();
i
++
)
{
{
if
(
CPoint
(
i
)
!=
aRhs
.
CPoint
(
i
)
)
if
(
CPoint
(
i
)
!=
aRhs
.
CPoint
(
i
)
)
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
private
:
private
:
/// array of vertices
/// array of vertices
std
::
vector
<
VECTOR2I
>
m_points
;
std
::
vector
<
VECTOR2I
>
m_points
;
/// is the line chain closed?
/// is the line chain closed?
bool
m_closed
;
bool
m_closed
;
/// cached bounding box
/// cached bounding box
BOX2I
m_bbox
;
BOX2I
m_bbox
;
};
};
#endif // __SHAPE_LINE_CHAIN
#endif // __SHAPE_LINE_CHAIN
include/geometry/shape_rect.h
View file @
22045b61
...
@@ -31,114 +31,114 @@
...
@@ -31,114 +31,114 @@
#include <geometry/seg.h>
#include <geometry/seg.h>
class
SHAPE_RECT
:
public
SHAPE
{
class
SHAPE_RECT
:
public
SHAPE
{
public
:
public
:
/**
/**
* Constructor
* Constructor
* Creates an empty (0-sized) rectangle
* Creates an empty (0-sized) rectangle
*/
*/
SHAPE_RECT
()
:
SHAPE_RECT
()
:
SHAPE
(
SH_RECT
),
m_w
(
0
),
m_h
(
0
)
{};
SHAPE
(
SH_RECT
),
m_w
(
0
),
m_h
(
0
)
{};
/**
/**
* Constructor
* Constructor
* Creates a rectangle defined by top-left corner (aX0, aY0), width aW and height aH.
* Creates a rectangle defined by top-left corner (aX0, aY0), width aW and height aH.
*/
*/
SHAPE_RECT
(
int
aX0
,
int
aY0
,
int
aW
,
int
aH
)
:
SHAPE_RECT
(
int
aX0
,
int
aY0
,
int
aW
,
int
aH
)
:
SHAPE
(
SH_RECT
),
m_p0
(
aX0
,
aY0
),
m_w
(
aW
),
m_h
(
aH
)
{};
SHAPE
(
SH_RECT
),
m_p0
(
aX0
,
aY0
),
m_w
(
aW
),
m_h
(
aH
)
{};
/**
/**
* Constructor
* Constructor
* Creates a rectangle defined by top-left corner aP0, width aW and height aH.
* Creates a rectangle defined by top-left corner aP0, width aW and height aH.
*/
*/
SHAPE_RECT
(
const
VECTOR2I
&
aP0
,
int
aW
,
int
aH
)
:
SHAPE_RECT
(
const
VECTOR2I
&
aP0
,
int
aW
,
int
aH
)
:
SHAPE
(
SH_RECT
),
m_p0
(
aP0
),
m_w
(
aW
),
m_h
(
aH
)
{};
SHAPE
(
SH_RECT
),
m_p0
(
aP0
),
m_w
(
aW
),
m_h
(
aH
)
{};
/// @copydoc SHAPE::BBox()
/// @copydoc SHAPE::BBox()
const
BOX2I
BBox
(
int
aClearance
=
0
)
const
const
BOX2I
BBox
(
int
aClearance
=
0
)
const
{
{
BOX2I
bbox
(
VECTOR2I
(
m_p0
.
x
-
aClearance
,
m_p0
.
y
-
aClearance
),
BOX2I
bbox
(
VECTOR2I
(
m_p0
.
x
-
aClearance
,
m_p0
.
y
-
aClearance
),
VECTOR2I
(
m_w
+
2
*
aClearance
,
m_h
+
2
*
aClearance
)
);
VECTOR2I
(
m_w
+
2
*
aClearance
,
m_h
+
2
*
aClearance
)
);
//printf("bb : %s\n",bbox.Format().c_str());
//printf("bb : %s\n",bbox.Format().c_str());
return
bbox
;
return
bbox
;
}
}
/**
/**
* Function Diagonal()
* Function Diagonal()
*
*
* Returns length of the diagonal of the rectangle
* Returns length of the diagonal of the rectangle
* @return diagonal length
* @return diagonal length
*/
*/
int
Diagonal
()
const
int
Diagonal
()
const
{
{
return
VECTOR2I
(
m_w
,
m_h
).
EuclideanNorm
();
return
VECTOR2I
(
m_w
,
m_h
).
EuclideanNorm
();
}
}
/// @copydoc SHAPE::Collide()
/// @copydoc SHAPE::Collide()
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
=
0
)
const
bool
Collide
(
const
SEG
&
aSeg
,
int
aClearance
=
0
)
const
{
{
//VECTOR2I pmin = VECTOR2I(std::min(aSeg.a.x, aSeg.b.x), std::min(aSeg.a.y, aSeg.b.y));
//VECTOR2I pmin = VECTOR2I(std::min(aSeg.a.x, aSeg.b.x), std::min(aSeg.a.y, aSeg.b.y));
//VECTOR2I pmax = VECTOR2I(std::max(aSeg.a.x, aSeg.b.x), std::max(aSeg.a.y, aSeg.b.y));
//VECTOR2I pmax = VECTOR2I(std::max(aSeg.a.x, aSeg.b.x), std::max(aSeg.a.y, aSeg.b.y));
//BOX2I r(pmin, VECTOR2I(pmax.x - pmin.x, pmax.y - pmin.y));
//BOX2I r(pmin, VECTOR2I(pmax.x - pmin.x, pmax.y - pmin.y));
//if (BBox(0).SquaredDistance(r) > aClearance * aClearance)
//if (BBox(0).SquaredDistance(r) > aClearance * aClearance)
//
return false;
//
return false;
if
(
BBox
(
0
).
Contains
(
aSeg
.
a
)
||
BBox
(
0
).
Contains
(
aSeg
.
b
)
)
if
(
BBox
(
0
).
Contains
(
aSeg
.
a
)
||
BBox
(
0
).
Contains
(
aSeg
.
b
)
)
return
true
;
return
true
;
VECTOR2I
vts
[]
=
{
VECTOR2I
(
m_p0
.
x
,
m_p0
.
y
),
VECTOR2I
vts
[]
=
{
VECTOR2I
(
m_p0
.
x
,
m_p0
.
y
),
VECTOR2I
(
m_p0
.
x
,
m_p0
.
y
+
m_h
),
VECTOR2I
(
m_p0
.
x
,
m_p0
.
y
+
m_h
),
VECTOR2I
(
m_p0
.
x
+
m_w
,
m_p0
.
y
+
m_h
),
VECTOR2I
(
m_p0
.
x
+
m_w
,
m_p0
.
y
+
m_h
),
VECTOR2I
(
m_p0
.
x
+
m_w
,
m_p0
.
y
),
VECTOR2I
(
m_p0
.
x
+
m_w
,
m_p0
.
y
),
VECTOR2I
(
m_p0
.
x
,
m_p0
.
y
)
};
VECTOR2I
(
m_p0
.
x
,
m_p0
.
y
)
};
for
(
int
i
=
0
;
i
<
4
;
i
++
)
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
{
SEG
s
(
vts
[
i
],
vts
[
i
+
1
],
i
);
SEG
s
(
vts
[
i
],
vts
[
i
+
1
],
i
);
if
(
s
.
Distance
(
aSeg
)
<=
aClearance
)
if
(
s
.
Distance
(
aSeg
)
<=
aClearance
)
return
true
;
return
true
;
}
}
return
false
;
return
false
;
};
};
/**
/**
* Function GetPosition()
* Function GetPosition()
*
*
* @return top-left corner of the rectangle
* @return top-left corner of the rectangle
*/
*/
const
VECTOR2I
&
GetPosition
()
const
{
return
m_p0
;
}
const
VECTOR2I
&
GetPosition
()
const
{
return
m_p0
;
}
/**
/**
* Function GetSize()
* Function GetSize()
*
*
* @return size of the rectangle
* @return size of the rectangle
*/
*/
const
VECTOR2I
GetSize
()
const
{
return
VECTOR2I
(
m_w
,
m_h
);
}
const
VECTOR2I
GetSize
()
const
{
return
VECTOR2I
(
m_w
,
m_h
);
}
/**
/**
* Function GetWidth()
* Function GetWidth()
*
*
* @return width of the rectangle
* @return width of the rectangle
*/
*/
const
int
GetWidth
()
const
{
return
m_w
;
}
const
int
GetWidth
()
const
{
return
m_w
;
}
/**
/**
* Function GetHeight()
* Function GetHeight()
*
*
* @return height of the rectangle
* @return height of the rectangle
*/
*/
const
int
GetHeight
()
const
{
return
m_h
;
}
const
int
GetHeight
()
const
{
return
m_h
;
}
private
:
private
:
///> Top-left corner
///> Top-left corner
VECTOR2I
m_p0
;
VECTOR2I
m_p0
;
///> Width
///> Width
int
m_w
;
int
m_w
;
///> Height
///> Height
int
m_h
;
int
m_h
;
};
};
#endif // __SHAPE_RECT_H
#endif // __SHAPE_RECT_H
include/math/box2.h
View file @
22045b61
...
@@ -66,7 +66,7 @@ public:
...
@@ -66,7 +66,7 @@ public:
BOX2
(
const
Vec
&
aPos
,
const
Vec
&
aSize
)
:
BOX2
(
const
Vec
&
aPos
,
const
Vec
&
aSize
)
:
m_Pos
(
aPos
),
m_Pos
(
aPos
),
m_Size
(
aSize
)
m_Size
(
aSize
)
{
{
Normalize
();
Normalize
();
}
}
...
@@ -420,7 +420,7 @@ public:
...
@@ -420,7 +420,7 @@ public:
ecoord_type
y2
=
m_Pos
.
y
+
m_Size
.
y
;
ecoord_type
y2
=
m_Pos
.
y
+
m_Size
.
y
;
ecoord_type
xdiff
=
std
::
max
(
aP
.
x
<
m_Pos
.
x
?
m_Pos
.
x
-
aP
.
x
:
m_Pos
.
x
-
x2
,
(
ecoord_type
)
0
);
ecoord_type
xdiff
=
std
::
max
(
aP
.
x
<
m_Pos
.
x
?
m_Pos
.
x
-
aP
.
x
:
m_Pos
.
x
-
x2
,
(
ecoord_type
)
0
);
ecoord_type
ydiff
=
std
::
max
(
aP
.
y
<
m_Pos
.
y
?
m_Pos
.
y
-
aP
.
y
:
m_Pos
.
y
-
y2
,
(
ecoord_type
)
0
);
ecoord_type
ydiff
=
std
::
max
(
aP
.
y
<
m_Pos
.
y
?
m_Pos
.
y
-
aP
.
y
:
m_Pos
.
y
-
y2
,
(
ecoord_type
)
0
);
return
xdiff
*
xdiff
+
ydiff
*
ydiff
;
return
xdiff
*
xdiff
+
ydiff
*
ydiff
;
}
}
ecoord_type
Distance
(
const
Vec
&
aP
)
const
ecoord_type
Distance
(
const
Vec
&
aP
)
const
...
...
include/math/vector2d.h
View file @
22045b61
...
@@ -224,7 +224,7 @@ public:
...
@@ -224,7 +224,7 @@ public:
/// Division with a factor
/// Division with a factor
VECTOR2
<
T
>
operator
/
(
const
T
&
aFactor
)
const
;
VECTOR2
<
T
>
operator
/
(
const
T
&
aFactor
)
const
;
/// Equality operator
/// Equality operator
const
bool
operator
==
(
const
VECTOR2
<
T
>&
aVector
)
const
;
const
bool
operator
==
(
const
VECTOR2
<
T
>&
aVector
)
const
;
...
...
include/tool/context_menu.h
View file @
22045b61
...
@@ -37,105 +37,105 @@ class TOOL_INTERACTIVE;
...
@@ -37,105 +37,105 @@ class TOOL_INTERACTIVE;
* Defines the structure of a context (usually right-click) popup menu
* Defines the structure of a context (usually right-click) popup menu
* for a given tool.
* for a given tool.
*/
*/
class
CONTEXT_MENU
class
CONTEXT_MENU
{
{
public
:
public
:
///> Default constructor
///> Default constructor
CONTEXT_MENU
();
CONTEXT_MENU
();
///> Copy constructor
///> Copy constructor
CONTEXT_MENU
(
const
CONTEXT_MENU
&
aMenu
);
CONTEXT_MENU
(
const
CONTEXT_MENU
&
aMenu
);
/**
/**
* Function SetTitle()
* Function SetTitle()
* Sets title for the context menu. The title is shown as a text label shown on the top of
* Sets title for the context menu. The title is shown as a text label shown on the top of
* the menu.
* the menu.
* @param aTitle is the new title.
* @param aTitle is the new title.
*/
*/
void
SetTitle
(
const
wxString
&
aTitle
);
void
SetTitle
(
const
wxString
&
aTitle
);
/**
/**
* Function Add()
* Function Add()
* Adds an entry to the menu. After highlighting/selecting the entry, a TOOL_EVENT command is
* Adds an entry to the menu. After highlighting/selecting the entry, a TOOL_EVENT command is
* sent that contains ID of the entry.
* sent that contains ID of the entry.
* @param aLabel is the text label show in the menu.
* @param aLabel is the text label show in the menu.
* @param aId is the ID that is sent in the TOOL_EVENT. It should be unique for every entry.
* @param aId is the ID that is sent in the TOOL_EVENT. It should be unique for every entry.
*/
*/
void
Add
(
const
wxString
&
aLabel
,
int
aId
);
void
Add
(
const
wxString
&
aLabel
,
int
aId
);
/**
/**
* Function Add()
* Function Add()
* Adds an entry to the menu, basing on the TOOL_ACTION object. After selecting the entry,
* Adds an entry to the menu, basing on the TOOL_ACTION object. After selecting the entry,
* a TOOL_EVENT command containing name of the action is sent.
* a TOOL_EVENT command containing name of the action is sent.
* @param aAction is the action to be added to menu entry.
* @param aAction is the action to be added to menu entry.
*/
*/
void
Add
(
const
TOOL_ACTION
&
aAction
);
void
Add
(
const
TOOL_ACTION
&
aAction
);
/**
/**
* Function Clear()
* Function Clear()
* Removes all the entries from the menu (as well as its title). It leaves the menu in the
* Removes all the entries from the menu (as well as its title). It leaves the menu in the
* initial state.
* initial state.
*/
*/
void
Clear
();
void
Clear
();
/**
/**
* Function GetMenu()
* Function GetMenu()
* Returns the instance of wxMenu object used to display the menu.
* Returns the instance of wxMenu object used to display the menu.
*/
*/
wxMenu
*
GetMenu
()
const
wxMenu
*
GetMenu
()
const
{
{
return
const_cast
<
wxMenu
*>
(
&
m_menu
);
return
const_cast
<
wxMenu
*>
(
&
m_menu
);
}
}
private
:
private
:
///> Class CMEventHandler takes care of handling menu events. After reception of particular
///> Class CMEventHandler takes care of handling menu events. After reception of particular
///> events, it translates them to TOOL_EVENTs that may control tools.
///> events, it translates them to TOOL_EVENTs that may control tools.
class
CMEventHandler
:
public
wxEvtHandler
class
CMEventHandler
:
public
wxEvtHandler
{
{
public
:
public
:
///> Default constructor
///> Default constructor
///> aMenu is the CONTEXT_MENU instance for which it handles events.
///> aMenu is the CONTEXT_MENU instance for which it handles events.
CMEventHandler
(
CONTEXT_MENU
*
aMenu
)
:
m_menu
(
aMenu
)
{};
CMEventHandler
(
CONTEXT_MENU
*
aMenu
)
:
m_menu
(
aMenu
)
{};
///> Handler for menu events.
///> Handler for menu events.
void
onEvent
(
wxEvent
&
aEvent
);
void
onEvent
(
wxEvent
&
aEvent
);
private
:
private
:
///> CONTEXT_MENU instance for which it handles events.
///> CONTEXT_MENU instance for which it handles events.
CONTEXT_MENU
*
m_menu
;
CONTEXT_MENU
*
m_menu
;
};
};
friend
class
TOOL_INTERACTIVE
;
friend
class
TOOL_INTERACTIVE
;
/**
/**
* Function setTool()
* Function setTool()
* Sets a tool that is the creator of the menu.
* Sets a tool that is the creator of the menu.
* @param aTool is the tool that created the menu.
* @param aTool is the tool that created the menu.
*/
*/
void
setTool
(
TOOL_INTERACTIVE
*
aTool
)
void
setTool
(
TOOL_INTERACTIVE
*
aTool
)
{
{
m_tool
=
aTool
;
m_tool
=
aTool
;
}
}
/**
/**
* Function getHotKeyDescription()
* Function getHotKeyDescription()
* Returns a hot key in the string format accepted by wxMenu.
* Returns a hot key in the string format accepted by wxMenu.
* @param aAction is the action with hot key to be translated..
* @param aAction is the action with hot key to be translated..
* @return Hot key in the string format compatible with wxMenu.
* @return Hot key in the string format compatible with wxMenu.
*/
*/
std
::
string
getHotKeyDescription
(
const
TOOL_ACTION
&
aAction
)
const
;
std
::
string
getHotKeyDescription
(
const
TOOL_ACTION
&
aAction
)
const
;
///> Flag indicating that the menu title was set up.
///> Flag indicating that the menu title was set up.
bool
m_titleSet
;
bool
m_titleSet
;
///> Instance of wxMenu used for display of the context menu.
///> Instance of wxMenu used for display of the context menu.
wxMenu
m_menu
;
wxMenu
m_menu
;
///> Instance of menu event handler.
///> Instance of menu event handler.
CMEventHandler
m_handler
;
CMEventHandler
m_handler
;
///> Creator of the menu
///> Creator of the menu
TOOL_INTERACTIVE
*
m_tool
;
TOOL_INTERACTIVE
*
m_tool
;
/// Menu items with ID higher than that are considered TOOL_ACTIONs
/// Menu items with ID higher than that are considered TOOL_ACTIONs
static
const
int
m_actionId
=
10000
;
static
const
int
m_actionId
=
10000
;
...
...
include/tool/coroutine.h
View file @
22045b61
...
@@ -34,13 +34,13 @@
...
@@ -34,13 +34,13 @@
/**
/**
Class COROUNTINE.
Class COROUNTINE.
Implements a coroutine. Wikipedia has a good explanation:
Implements a coroutine. Wikipedia has a good explanation:
"Coroutines are computer program components that generalize subroutines to
"Coroutines are computer program components that generalize subroutines to
allow multiple entry points for suspending and resuming execution at certain locations.
allow multiple entry points for suspending and resuming execution at certain locations.
Coroutines are well-suited for implementing more familiar program components such as cooperative
Coroutines are well-suited for implementing more familiar program components such as cooperative
tasks, exceptions, event loop, iterators, infinite lists and pipes."
tasks, exceptions, event loop, iterators, infinite lists and pipes."
In other words, a coroutine can be considered a lightweight thread - which can be
In other words, a coroutine can be considered a lightweight thread - which can be
preempted only when it deliberately yields the control to the caller. This way,
preempted only when it deliberately yields the control to the caller. This way,
we avoid concurrency problems such as locking / race conditions.
we avoid concurrency problems such as locking / race conditions.
...
@@ -56,82 +56,82 @@ template<class ReturnType, class ArgType>
...
@@ -56,82 +56,82 @@ template<class ReturnType, class ArgType>
class
COROUTINE
class
COROUTINE
{
{
public
:
public
:
COROUTINE
()
COROUTINE
()
{
{
m_stackSize
=
c_defaultStackSize
;
m_stackSize
=
c_defaultStackSize
;
m_stack
=
NULL
;
m_stack
=
NULL
;
m_saved
=
NULL
;
m_saved
=
NULL
;
}
}
/**
/**
* Constructor
* Constructor
* Creates a coroutine from a member method of an object
* Creates a coroutine from a member method of an object
*/
*/
template
<
class
T
>
template
<
class
T
>
COROUTINE
(
T
*
object
,
ReturnType
(
T
::*
ptr
)(
ArgType
)
)
:
COROUTINE
(
T
*
object
,
ReturnType
(
T
::*
ptr
)(
ArgType
)
)
:
m_func
(
object
,
ptr
),
m_saved
(
NULL
),
m_stack
(
NULL
),
m_stackSize
(
c_defaultStackSize
)
m_func
(
object
,
ptr
),
m_saved
(
NULL
),
m_stack
(
NULL
),
m_stackSize
(
c_defaultStackSize
)
{
{
}
}
/**
/**
* Constructor
* Constructor
* Creates a coroutine from a delegate object
* Creates a coroutine from a delegate object
*/
*/
COROUTINE
(
DELEGATE
<
ReturnType
,
ArgType
>
aEntry
)
:
COROUTINE
(
DELEGATE
<
ReturnType
,
ArgType
>
aEntry
)
:
m_func
(
aEntry
),
m_saved
(
NULL
),
m_stack
(
NULL
),
m_stackSize
(
c_defaultStackSize
)
m_func
(
aEntry
),
m_saved
(
NULL
),
m_stack
(
NULL
),
m_stackSize
(
c_defaultStackSize
)
{};
{};
~
COROUTINE
()
~
COROUTINE
()
{
{
if
(
m_saved
)
if
(
m_saved
)
delete
m_saved
;
delete
m_saved
;
if
(
m_stack
)
if
(
m_stack
)
free
(
m_stack
);
free
(
m_stack
);
}
}
/**
/**
* Function Yield()
* Function Yield()
*
*
* Stops execution of the coroutine and returns control to the caller.
* Stops execution of the coroutine and returns control to the caller.
* After a yield, Call() or Resume() methods invoked by the caller will
* After a yield, Call() or Resume() methods invoked by the caller will
* immediately return true, indicating that we are not done yet, just asleep.
* immediately return true, indicating that we are not done yet, just asleep.
*/
*/
void
Yield
()
void
Yield
()
{
{
boost
::
context
::
jump_fcontext
(
m_self
,
m_saved
,
0
);
boost
::
context
::
jump_fcontext
(
m_self
,
m_saved
,
0
);
}
}
/**
/**
* Function Yield()
* Function Yield()
*
*
* Yield with a value - passes a value of given type to the caller.
* Yield with a value - passes a value of given type to the caller.
* Useful for implementing generator objects.
* Useful for implementing generator objects.
*/
*/
void
Yield
(
ReturnType
&
retVal
)
void
Yield
(
ReturnType
&
retVal
)
{
{
m_retVal
=
retVal
;
m_retVal
=
retVal
;
boost
::
context
::
jump_fcontext
(
m_self
,
m_saved
,
0
);
boost
::
context
::
jump_fcontext
(
m_self
,
m_saved
,
0
);
}
}
/**
/**
<F11>* Function SetEntry()
<F11>* Function SetEntry()
*
*
* Defines the entry point for the coroutine, if not set in the constructor.
* Defines the entry point for the coroutine, if not set in the constructor.
*/
*/
void
SetEntry
(
DELEGATE
<
ReturnType
,
ArgType
>
aEntry
)
void
SetEntry
(
DELEGATE
<
ReturnType
,
ArgType
>
aEntry
)
{
{
m_func
=
aEntry
;
m_func
=
aEntry
;
}
}
/* Function Call()
/* Function Call()
*
*
* Starts execution of a coroutine, passing args as its arguments.
* Starts execution of a coroutine, passing args as its arguments.
* @return true, if the coroutine has yielded and false if it has finished its
* @return true, if the coroutine has yielded and false if it has finished its
* execution (returned).
* execution (returned).
*/
*/
bool
Call
(
ArgType
args
)
bool
Call
(
ArgType
args
)
{
{
// fixme: Clean up stack stuff. Add a guard
// fixme: Clean up stack stuff. Add a guard
m_stack
=
malloc
(
c_defaultStackSize
);
m_stack
=
malloc
(
c_defaultStackSize
);
// align to 16 bytes
// align to 16 bytes
...
@@ -145,87 +145,87 @@ public:
...
@@ -145,87 +145,87 @@ public:
// off we go!
// off we go!
boost
::
context
::
jump_fcontext
(
m_saved
,
m_self
,
reinterpret_cast
<
intptr_t
>
(
this
)
);
boost
::
context
::
jump_fcontext
(
m_saved
,
m_self
,
reinterpret_cast
<
intptr_t
>
(
this
)
);
return
m_running
;
return
m_running
;
}
}
/**
/**
* Function Resume()
* Function Resume()
*
*
* Resumes execution of a previously yielded coroutine.
* Resumes execution of a previously yielded coroutine.
* @return true, if the coroutine has yielded again and false if it has finished its
* @return true, if the coroutine has yielded again and false if it has finished its
* execution (returned).
* execution (returned).
*/
*/
bool
Resume
()
bool
Resume
()
{
{
boost
::
context
::
jump_fcontext
(
m_saved
,
m_self
,
0
);
boost
::
context
::
jump_fcontext
(
m_saved
,
m_self
,
0
);
return
m_running
;
return
m_running
;
}
}
/**
/**
* Function ReturnValue()
* Function ReturnValue()
*
*
* Returns the yielded value (the argument Yield() was called with)
* Returns the yielded value (the argument Yield() was called with)
*/
*/
const
ReturnType
&
ReturnValue
()
const
const
ReturnType
&
ReturnValue
()
const
{
{
return
m_retVal
;
return
m_retVal
;
}
}
/**
/**
* Function Running()
* Function Running()
*
*
* @return true, if the coroutine is active
* @return true, if the coroutine is active
*/
*/
bool
Running
()
const
bool
Running
()
const
{
{
return
m_running
;
return
m_running
;
}
}
private
:
private
:
static
const
int
c_defaultStackSize
=
2000000
;
// fixme: make configurable
static
const
int
c_defaultStackSize
=
2000000
;
// fixme: make configurable
/* real entry point of the coroutine */
/* real entry point of the coroutine */
static
void
callerStub
(
intptr_t
data
)
static
void
callerStub
(
intptr_t
data
)
{
{
// get pointer to self
// get pointer to self
COROUTINE
<
ReturnType
,
ArgType
>*
cor
=
reinterpret_cast
<
COROUTINE
<
ReturnType
,
ArgType
>*>
(
data
);
COROUTINE
<
ReturnType
,
ArgType
>*
cor
=
reinterpret_cast
<
COROUTINE
<
ReturnType
,
ArgType
>*>
(
data
);
// call the coroutine method
// call the coroutine method
cor
->
m_retVal
=
cor
->
m_func
(
*
cor
->
m_args
);
cor
->
m_retVal
=
cor
->
m_func
(
*
cor
->
m_args
);
cor
->
m_running
=
false
;
cor
->
m_running
=
false
;
// go back to wherever we came from.
// go back to wherever we came from.
boost
::
context
::
jump_fcontext
(
cor
->
m_self
,
cor
->
m_saved
,
0
);
//reinterpret_cast<intptr_t>( this ));
boost
::
context
::
jump_fcontext
(
cor
->
m_self
,
cor
->
m_saved
,
0
);
//reinterpret_cast<intptr_t>( this ));
}
}
template
<
typename
T
>
struct
strip_ref
template
<
typename
T
>
struct
strip_ref
{
{
typedef
T
result
;
typedef
T
result
;
};
};
template
<
typename
T
>
struct
strip_ref
<
T
&>
template
<
typename
T
>
struct
strip_ref
<
T
&>
{
{
typedef
T
result
;
typedef
T
result
;
};
};
DELEGATE
<
ReturnType
,
ArgType
>
m_func
;
DELEGATE
<
ReturnType
,
ArgType
>
m_func
;
///< pointer to coroutine entry arguments. Stripped of references
///< pointer to coroutine entry arguments. Stripped of references
///< to avoid compiler errors.
///< to avoid compiler errors.
typename
strip_ref
<
ArgType
>::
result
*
m_args
;
typename
strip_ref
<
ArgType
>::
result
*
m_args
;
ReturnType
m_retVal
;
ReturnType
m_retVal
;
///< saved caller context
///< saved caller context
boost
::
context
::
fcontext_t
*
m_saved
;
boost
::
context
::
fcontext_t
*
m_saved
;
///< saved coroutine context
///< saved coroutine context
boost
::
context
::
fcontext_t
*
m_self
;
boost
::
context
::
fcontext_t
*
m_self
;
///< coroutine stack
///< coroutine stack
void
*
m_stack
;
void
*
m_stack
;
size_t
m_stackSize
;
size_t
m_stackSize
;
bool
m_running
;
bool
m_running
;
};
};
#endif
#endif
include/tool/delegate.h
View file @
22045b61
...
@@ -28,38 +28,38 @@
...
@@ -28,38 +28,38 @@
/**
/**
* class DELEGATE
* class DELEGATE
* A trivial delegate (pointer to member method of an object) pattern implementation.
* A trivial delegate (pointer to member method of an object) pattern implementation.
* Check delegate_example.cpp for a coding sample.
* Check delegate_example.cpp for a coding sample.
*/
*/
template
<
class
ReturnType
,
class
Arg
>
template
<
class
ReturnType
,
class
Arg
>
class
DELEGATE
{
class
DELEGATE
{
public
:
public
:
typedef
ReturnType
(
DELEGATE
<
ReturnType
,
Arg
>::*
MemberPointer
)(
Arg
);
typedef
ReturnType
(
DELEGATE
<
ReturnType
,
Arg
>::*
MemberPointer
)(
Arg
);
typedef
ReturnType
_ReturnType
;
typedef
ReturnType
_ReturnType
;
typedef
Arg
_ArgType
;
typedef
Arg
_ArgType
;
DELEGATE
()
DELEGATE
()
{
{
}
}
template
<
class
T
>
template
<
class
T
>
DELEGATE
(
T
*
object
,
ReturnType
(
T
::*
ptr
)(
Arg
)
)
DELEGATE
(
T
*
object
,
ReturnType
(
T
::*
ptr
)(
Arg
)
)
{
{
m_ptr
=
reinterpret_cast
<
MemberPointer
>
(
ptr
);
m_ptr
=
reinterpret_cast
<
MemberPointer
>
(
ptr
);
m_object
=
reinterpret_cast
<
void
*>
(
object
);
m_object
=
reinterpret_cast
<
void
*>
(
object
);
};
};
ReturnType
operator
()(
Arg
a
)
const
ReturnType
operator
()(
Arg
a
)
const
{
{
DELEGATE
<
ReturnType
,
Arg
>
*
casted
=
reinterpret_cast
<
DELEGATE
<
ReturnType
,
Arg
>*>
(
m_object
);
DELEGATE
<
ReturnType
,
Arg
>
*
casted
=
reinterpret_cast
<
DELEGATE
<
ReturnType
,
Arg
>*>
(
m_object
);
return
(
casted
->*
m_ptr
)(
a
);
return
(
casted
->*
m_ptr
)(
a
);
}
}
private
:
private
:
MemberPointer
m_ptr
;
MemberPointer
m_ptr
;
void
*
m_object
;
void
*
m_object
;
};
};
/**
/**
...
@@ -67,32 +67,32 @@ private:
...
@@ -67,32 +67,32 @@ private:
* Same as DELEGATE, but with no arguments.
* Same as DELEGATE, but with no arguments.
*/
*/
template
<
class
ReturnType
>
template
<
class
ReturnType
>
class
DELEGATE0
{
class
DELEGATE0
{
public
:
public
:
typedef
ReturnType
(
DELEGATE0
<
ReturnType
>::*
MemberPointer
)();
typedef
ReturnType
(
DELEGATE0
<
ReturnType
>::*
MemberPointer
)();
typedef
ReturnType
_ReturnType
;
typedef
ReturnType
_ReturnType
;
DELEGATE0
()
DELEGATE0
()
{
{
}
}
template
<
class
T
>
template
<
class
T
>
DELEGATE0
(
T
*
object
,
ReturnType
(
T
::*
ptr
)(
)
)
DELEGATE0
(
T
*
object
,
ReturnType
(
T
::*
ptr
)(
)
)
{
{
m_ptr
=
reinterpret_cast
<
MemberPointer
>
(
ptr
);
m_ptr
=
reinterpret_cast
<
MemberPointer
>
(
ptr
);
m_object
=
reinterpret_cast
<
void
*>
(
object
);
m_object
=
reinterpret_cast
<
void
*>
(
object
);
};
};
ReturnType
operator
()(
)
const
ReturnType
operator
()(
)
const
{
{
DELEGATE0
<
ReturnType
>*
casted
=
reinterpret_cast
<
DELEGATE0
<
ReturnType
>*>
(
m_object
);
DELEGATE0
<
ReturnType
>*
casted
=
reinterpret_cast
<
DELEGATE0
<
ReturnType
>*>
(
m_object
);
return
(
casted
->*
m_ptr
)();
return
(
casted
->*
m_ptr
)();
}
}
private
:
private
:
MemberPointer
m_ptr
;
MemberPointer
m_ptr
;
void
*
m_object
;
void
*
m_object
;
};
};
#endif
#endif
include/tool/examples/coroutine_example.cpp
View file @
22045b61
...
@@ -9,40 +9,40 @@ typedef COROUTINE<int, int> MyCoroutine;
...
@@ -9,40 +9,40 @@ typedef COROUTINE<int, int> MyCoroutine;
class
MyClass
{
class
MyClass
{
public
:
public
:
int
CountTo
(
int
n
)
int
CountTo
(
int
n
)
{
{
printf
(
"%s: Coroutine says hi. I will count from 1 to %d and yield each value.
\n
"
,
__FUNCTION__
,
n
);
printf
(
"%s: Coroutine says hi. I will count from 1 to %d and yield each value.
\n
"
,
__FUNCTION__
,
n
);
for
(
int
i
=
1
;
i
<=
n
;
i
++
)
for
(
int
i
=
1
;
i
<=
n
;
i
++
)
{
{
printf
(
"%s: Yielding %d
\n
"
,
__FUNCTION__
,
i
);
printf
(
"%s: Yielding %d
\n
"
,
__FUNCTION__
,
i
);
cofunc
.
Yield
(
i
);
cofunc
.
Yield
(
i
);
}
}
}
}
void
Run
()
void
Run
()
{
{
cofunc
=
MyCoroutine
(
this
,
&
MyClass
::
CountTo
);
cofunc
=
MyCoroutine
(
this
,
&
MyClass
::
CountTo
);
printf
(
"%s: Calling coroutine that will count from 1 to 5.
\n
"
,
__FUNCTION__
);
printf
(
"%s: Calling coroutine that will count from 1 to 5.
\n
"
,
__FUNCTION__
);
cofunc
.
Call
(
5
);
cofunc
.
Call
(
5
);
while
(
cofunc
.
Running
())
while
(
cofunc
.
Running
())
{
{
printf
(
"%s: Got value: %d
\n
"
,
__FUNCTION__
,
cofunc
.
ReturnValue
());
printf
(
"%s: Got value: %d
\n
"
,
__FUNCTION__
,
cofunc
.
ReturnValue
());
cofunc
.
Resume
();
cofunc
.
Resume
();
}
}
printf
(
"%s: Done!
\n
"
,
__FUNCTION__
);
printf
(
"%s: Done!
\n
"
,
__FUNCTION__
);
}
}
MyCoroutine
cofunc
;
MyCoroutine
cofunc
;
};
};
main
()
main
()
{
{
MyClass
obj
;
MyClass
obj
;
obj
.
Run
();
obj
.
Run
();
return
0
;
return
0
;
}
}
include/tool/examples/delegate_example.cpp
View file @
22045b61
...
@@ -7,29 +7,29 @@ using namespace std;
...
@@ -7,29 +7,29 @@ using namespace std;
class
MyClass
{
class
MyClass
{
public
:
public
:
int
MyMethod
(
const
string
&
arg
)
int
MyMethod
(
const
string
&
arg
)
{
{
printf
(
"MyClass(this = %p)::MyMethod() called with string '%s', length %d
\n
"
,
this
,
arg
.
c_str
(),
arg
.
length
());
printf
(
"MyClass(this = %p)::MyMethod() called with string '%s', length %d
\n
"
,
this
,
arg
.
c_str
(),
arg
.
length
());
return
arg
.
length
();
return
arg
.
length
();
}
}
};
};
typedef
DELEGATE
<
int
,
const
string
&>
MyDelegate
;
typedef
DELEGATE
<
int
,
const
string
&>
MyDelegate
;
main
()
main
()
{
{
MyClass
t1
;
MyClass
t1
;
MyClass
t2
;
MyClass
t2
;
MyDelegate
ptr1
(
&
t1
,
&
MyClass
::
MyMethod
);
MyDelegate
ptr1
(
&
t1
,
&
MyClass
::
MyMethod
);
MyDelegate
ptr2
(
&
t2
,
&
MyClass
::
MyMethod
);
MyDelegate
ptr2
(
&
t2
,
&
MyClass
::
MyMethod
);
int
retval1
,
retval2
;
int
retval1
,
retval2
;
retval1
=
ptr1
(
"apples"
);
retval1
=
ptr1
(
"apples"
);
retval2
=
ptr2
(
"cherries"
);
retval2
=
ptr2
(
"cherries"
);
printf
(
"Object 1 returned %d, object 2 returned %d
\n
"
,
retval1
,
retval2
);
printf
(
"Object 1 returned %d, object 2 returned %d
\n
"
,
retval1
,
retval2
);
return
0
;
return
0
;
}
}
include/tool/tool_base.h
View file @
22045b61
...
@@ -59,128 +59,128 @@ typedef DELEGATE<int, TOOL_EVENT&> TOOL_STATE_FUNC;
...
@@ -59,128 +59,128 @@ typedef DELEGATE<int, TOOL_EVENT&> TOOL_STATE_FUNC;
* Base abstract interface for all kinds of tools.
* Base abstract interface for all kinds of tools.
*/
*/
class
TOOL_BASE
class
TOOL_BASE
{
{
public
:
public
:
TOOL_BASE
(
TOOL_Type
aType
,
TOOL_ID
aId
,
const
std
::
string
&
aName
=
std
::
string
(
""
)
)
:
TOOL_BASE
(
TOOL_Type
aType
,
TOOL_ID
aId
,
const
std
::
string
&
aName
=
std
::
string
(
""
)
)
:
m_type
(
aType
),
m_type
(
aType
),
m_toolId
(
aId
),
m_toolId
(
aId
),
m_toolName
(
aName
),
m_toolName
(
aName
),
m_toolMgr
(
NULL
){};
m_toolMgr
(
NULL
){};
virtual
~
TOOL_BASE
()
{};
virtual
~
TOOL_BASE
()
{};
/**
/**
* Function GetType()
* Function GetType()
* Returns the type of the tool.
* Returns the type of the tool.
* @return The type of the tool.
* @return The type of the tool.
*/
*/
TOOL_Type
GetType
()
const
TOOL_Type
GetType
()
const
{
{
return
m_type
;
return
m_type
;
}
}
/**
/**
* Function GetId()
* Function GetId()
* Returns the unique identifier of the tool. The identifier is set by an instance of
* Returns the unique identifier of the tool. The identifier is set by an instance of
* TOOL_MANAGER.
* TOOL_MANAGER.
* @return Identifier of the tool.
* @return Identifier of the tool.
*/
*/
TOOL_ID
GetId
()
const
TOOL_ID
GetId
()
const
{
{
return
m_toolId
;
return
m_toolId
;
}
}
/**
/**
* Function GetName()
* Function GetName()
* Returns the name of the tool. Tool names are expected to obey the format:
* Returns the name of the tool. Tool names are expected to obey the format:
* application.ToolName (eg. pcbnew.InteractiveSelection).
* application.ToolName (eg. pcbnew.InteractiveSelection).
* @return The name of the tool.
* @return The name of the tool.
*/
*/
const
std
::
string
&
GetName
()
const
const
std
::
string
&
GetName
()
const
{
{
return
m_toolName
;
return
m_toolName
;
}
}
/**
/**
* Function GetManager()
* Function GetManager()
* Returns the instance of TOOL_MANAGER that takes care of the tool.
* Returns the instance of TOOL_MANAGER that takes care of the tool.
* @return Instance of the TOOL_MANAGER. If there is no TOOL_MANAGER associated, it returns
* @return Instance of the TOOL_MANAGER. If there is no TOOL_MANAGER associated, it returns
* NULL.
* NULL.
*/
*/
TOOL_MANAGER
*
GetManager
()
const
TOOL_MANAGER
*
GetManager
()
const
{
{
return
m_toolMgr
;
return
m_toolMgr
;
}
}
protected
:
protected
:
friend
class
TOOL_MANAGER
;
friend
class
TOOL_MANAGER
;
/**
/**
* Function attachManager()
* Function attachManager()
*
*
* Sets the TOOL_MANAGER the tool will belong to.
* Sets the TOOL_MANAGER the tool will belong to.
* Called by TOOL_MANAGER::RegisterTool()
* Called by TOOL_MANAGER::RegisterTool()
*/
*/
void
attachManager
(
TOOL_MANAGER
*
aManager
);
void
attachManager
(
TOOL_MANAGER
*
aManager
);
/**
/**
* Function getView()
* Function getView()
*
*
* Returns the instance of VIEW object used in the application. It allows tools to draw.
* Returns the instance of VIEW object used in the application. It allows tools to draw.
* @return The instance of VIEW.
* @return The instance of VIEW.
*/
*/
KiGfx
::
VIEW
*
getView
()
const
;
KiGfx
::
VIEW
*
getView
()
const
;
/**
/**
* Function getViewControls()
* Function getViewControls()
*
*
* Returns the instance of VIEW_CONTROLS object used in the application. It allows tools to
* Returns the instance of VIEW_CONTROLS object used in the application. It allows tools to
* read & modify user input and its settings (eg. show cursor, enable snapping to grid, etc.)
* read & modify user input and its settings (eg. show cursor, enable snapping to grid, etc.)
* @return The instance of VIEW_CONTROLS.
* @return The instance of VIEW_CONTROLS.
*/
*/
KiGfx
::
VIEW_CONTROLS
*
getViewControls
()
const
;
KiGfx
::
VIEW_CONTROLS
*
getViewControls
()
const
;
/**
/**
* Function getEditFrame()
* Function getEditFrame()
*
*
* Returns the application window object, casted to requested user type.
* Returns the application window object, casted to requested user type.
*/
*/
template
<
typename
T
>
template
<
typename
T
>
T
*
getEditFrame
()
const
T
*
getEditFrame
()
const
{
{
return
static_cast
<
T
*>
(
getEditFrameInt
()
);
return
static_cast
<
T
*>
(
getEditFrameInt
()
);
}
}
/**
/**
* Function getModel()
* Function getModel()
*
*
* Returns the model object if it matches the requested type.
* Returns the model object if it matches the requested type.
*/
*/
template
<
typename
T
>
template
<
typename
T
>
T
*
getModel
(
KICAD_T
modelType
)
const
T
*
getModel
(
KICAD_T
modelType
)
const
{
{
EDA_ITEM
*
m
=
getModelInt
();
EDA_ITEM
*
m
=
getModelInt
();
return
static_cast
<
T
*>
(
m
);
return
static_cast
<
T
*>
(
m
);
}
}
///> Stores the type of the tool.
///> Stores the type of the tool.
TOOL_Type
m_type
;
TOOL_Type
m_type
;
///> Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
///> Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
TOOL_ID
m_toolId
;
TOOL_ID
m_toolId
;
///> Name of the tool. Names are expected to obey the format application.ToolName
///> Name of the tool. Names are expected to obey the format application.ToolName
///> (eg. pcbnew.InteractiveSelection).
///> (eg. pcbnew.InteractiveSelection).
std
::
string
m_toolName
;
std
::
string
m_toolName
;
TOOL_MANAGER
*
m_toolMgr
;
TOOL_MANAGER
*
m_toolMgr
;
private
:
private
:
// hide the implementation to avoid spreading half of
// hide the implementation to avoid spreading half of
// kicad and wxWidgets headers to the tools that may not need them at all!
// kicad and wxWidgets headers to the tools that may not need them at all!
EDA_ITEM
*
getModelInt
()
const
;
EDA_ITEM
*
getModelInt
()
const
;
wxWindow
*
getEditFrameInt
()
const
;
wxWindow
*
getEditFrameInt
()
const
;
};
};
#endif
#endif
include/tool/tool_dispatcher.h
View file @
22045b61
...
@@ -33,12 +33,12 @@ class TOOL_MANAGER;
...
@@ -33,12 +33,12 @@ class TOOL_MANAGER;
class
PCB_BASE_FRAME
;
class
PCB_BASE_FRAME
;
namespace
KiGfx
{
namespace
KiGfx
{
class
VIEW
;
class
VIEW
;
};
};
/**
/**
* Class TOOL_DISPATCHER
* Class TOOL_DISPATCHER
*
*
* - takes wx events,
* - takes wx events,
* - fixes all wx quirks (mouse warping, panning, ordering problems, etc)
* - fixes all wx quirks (mouse warping, panning, ordering problems, etc)
* - translates coordinates to world space
* - translates coordinates to world space
...
...
include/tool/tool_event.h
View file @
22045b61
...
@@ -42,63 +42,63 @@ class TOOL_MANAGER;
...
@@ -42,63 +42,63 @@ class TOOL_MANAGER;
*/
*/
enum
TOOL_EventCategory
enum
TOOL_EventCategory
{
{
TC_None
=
0x00
,
TC_None
=
0x00
,
TC_Mouse
=
0x01
,
TC_Mouse
=
0x01
,
TC_Keyboard
=
0x02
,
TC_Keyboard
=
0x02
,
TC_Command
=
0x04
,
TC_Command
=
0x04
,
TC_Message
=
0x08
,
TC_Message
=
0x08
,
TC_View
=
0x10
,
TC_View
=
0x10
,
TC_Any
=
0xffffffff
TC_Any
=
0xffffffff
};
};
enum
TOOL_Actions
enum
TOOL_Actions
{
{
// UI input events
// UI input events
TA_None
=
0x0000
,
TA_None
=
0x0000
,
TA_MouseClick
=
0x0001
,
TA_MouseClick
=
0x0001
,
TA_MouseUp
=
0x0002
,
TA_MouseUp
=
0x0002
,
TA_MouseDown
=
0x0004
,
TA_MouseDown
=
0x0004
,
TA_MouseDrag
=
0x0008
,
TA_MouseDrag
=
0x0008
,
TA_MouseMotion
=
0x0010
,
TA_MouseMotion
=
0x0010
,
TA_MouseWheel
=
0x0020
,
TA_MouseWheel
=
0x0020
,
TA_Mouse
=
0x003f
,
TA_Mouse
=
0x003f
,
TA_KeyUp
=
0x0040
,
TA_KeyUp
=
0x0040
,
TA_KeyDown
=
0x0080
,
TA_KeyDown
=
0x0080
,
TA_Keyboard
=
TA_KeyUp
|
TA_KeyDown
,
TA_Keyboard
=
TA_KeyUp
|
TA_KeyDown
,
// View related events
// View related events
TA_ViewRefresh
=
0x0100
,
TA_ViewRefresh
=
0x0100
,
TA_ViewZoom
=
0x0200
,
TA_ViewZoom
=
0x0200
,
TA_ViewPan
=
0x0400
,
TA_ViewPan
=
0x0400
,
TA_ViewDirty
=
0x0800
,
TA_ViewDirty
=
0x0800
,
TA_ChangeLayer
=
0x1000
,
TA_ChangeLayer
=
0x1000
,
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
// the context menu.
// the context menu.
TA_CancelTool
=
0x2000
,
TA_CancelTool
=
0x2000
,
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
// over one of choices. Used in dynamic highligting in disambiguation menu
// over one of choices. Used in dynamic highligting in disambiguation menu
TA_ContextMenuUpdate
=
0x4000
,
TA_ContextMenuUpdate
=
0x4000
,
// Context menu choice. Sent if the user picked something from the context menu or
// Context menu choice. Sent if the user picked something from the context menu or
// closed it without selecting anything.
// closed it without selecting anything.
TA_ContextMenuChoice
=
0x8000
,
TA_ContextMenuChoice
=
0x8000
,
// Tool action (allows to control tools)
// Tool action (allows to control tools)
TA_Action
=
0x10000
,
TA_Action
=
0x10000
,
TA_Any
=
0xffffffff
TA_Any
=
0xffffffff
};
};
enum
TOOL_MouseButtons
enum
TOOL_MouseButtons
{
{
MB_None
=
0x0
,
MB_None
=
0x0
,
MB_Left
=
0x1
,
MB_Left
=
0x1
,
MB_Right
=
0x2
,
MB_Right
=
0x2
,
MB_Middle
=
0x4
,
MB_Middle
=
0x4
,
MB_ButtonMask
=
MB_Left
|
MB_Right
|
MB_Middle
,
MB_ButtonMask
=
MB_Left
|
MB_Right
|
MB_Middle
,
MB_Any
=
0xffffffff
MB_Any
=
0xffffffff
};
};
enum
TOOL_Modifiers
enum
TOOL_Modifiers
...
@@ -120,14 +120,14 @@ enum TOOL_ActionScope
...
@@ -120,14 +120,14 @@ enum TOOL_ActionScope
/// Defines when a context menu is opened.
/// Defines when a context menu is opened.
enum
CONTEXT_MENU_TRIGGER
enum
CONTEXT_MENU_TRIGGER
{
{
CMENU_BUTTON
=
0
,
// On the right button
CMENU_BUTTON
=
0
,
// On the right button
CMENU_NOW
,
// Right now (after TOOL_INTERACTIVE::SetContextMenu)
CMENU_NOW
,
// Right now (after TOOL_INTERACTIVE::SetContextMenu)
CMENU_OFF
// Never
CMENU_OFF
// Never
};
};
/**
/**
* Class TOOL_EVENT
* Class TOOL_EVENT
*
*
* Generic, UI-independent tool event.
* Generic, UI-independent tool event.
*/
*/
class
TOOL_EVENT
class
TOOL_EVENT
...
@@ -359,9 +359,9 @@ private:
...
@@ -359,9 +359,9 @@ private:
typedef
boost
::
optional
<
TOOL_EVENT
>
OPT_TOOL_EVENT
;
typedef
boost
::
optional
<
TOOL_EVENT
>
OPT_TOOL_EVENT
;
/**
/**
* Class TOOL_EVENT_LIST
* Class TOOL_EVENT_LIST
*
*
* A list of TOOL_EVENTs, with overloaded || operators allowing for
* A list of TOOL_EVENTs, with overloaded || operators allowing for
* concatenating TOOL_EVENTs with little code.
* concatenating TOOL_EVENTs with little code.
*/
*/
...
@@ -473,20 +473,20 @@ private:
...
@@ -473,20 +473,20 @@ private:
inline
const
TOOL_EVENT_LIST
operator
||
(
const
TOOL_EVENT
&
a
,
const
TOOL_EVENT
&
b
)
inline
const
TOOL_EVENT_LIST
operator
||
(
const
TOOL_EVENT
&
a
,
const
TOOL_EVENT
&
b
)
{
{
TOOL_EVENT_LIST
l
;
TOOL_EVENT_LIST
l
;
l
.
Add
(
a
);
l
.
Add
(
a
);
l
.
Add
(
b
);
l
.
Add
(
b
);
return
l
;
return
l
;
}
}
inline
const
TOOL_EVENT_LIST
operator
||
(
const
TOOL_EVENT
&
a
,
const
TOOL_EVENT_LIST
&
b
)
inline
const
TOOL_EVENT_LIST
operator
||
(
const
TOOL_EVENT
&
a
,
const
TOOL_EVENT_LIST
&
b
)
{
{
TOOL_EVENT_LIST
l
(
b
);
TOOL_EVENT_LIST
l
(
b
);
l
.
Add
(
a
);
l
.
Add
(
a
);
return
l
;
return
l
;
}
}
#endif
#endif
include/tool/tool_interactive.h
View file @
22045b61
...
@@ -39,23 +39,23 @@ public:
...
@@ -39,23 +39,23 @@ public:
* Constructor
* Constructor
*
*
* Creates a tool with given id & name. The name must be unique. */
* Creates a tool with given id & name. The name must be unique. */
TOOL_INTERACTIVE
(
TOOL_ID
aId
,
const
std
::
string
&
aName
);
TOOL_INTERACTIVE
(
TOOL_ID
aId
,
const
std
::
string
&
aName
);
/**
/**
* Constructor
* Constructor
*
*
* Creates a tool with given name. The name must be unique. */
* Creates a tool with given name. The name must be unique. */
TOOL_INTERACTIVE
(
const
std
::
string
&
aName
);
TOOL_INTERACTIVE
(
const
std
::
string
&
aName
);
virtual
~
TOOL_INTERACTIVE
();
virtual
~
TOOL_INTERACTIVE
();
/**
/**
* Function Reset()
* Function Reset()
* Brings the tool to a known, initial state. If the tool claimed anything from
* Brings the tool to a known, initial state. If the tool claimed anything from
* the model or the view, it must release it when its reset.
* the model or the view, it must release it when its reset.
*/
*/
virtual
void
Reset
()
=
0
;
virtual
void
Reset
()
=
0
;
/**
/**
* Function Init()
* Function Init()
* Init() is called once upon a registration of the tool.
* Init() is called once upon a registration of the tool.
*
*
...
@@ -66,58 +66,58 @@ public:
...
@@ -66,58 +66,58 @@ public:
return
true
;
return
true
;
}
}
/**
/**
* Function SetContextMenu()
* Function SetContextMenu()
*
*
* Assigns a context menu and tells when it should be activated.
* Assigns a context menu and tells when it should be activated.
* @param aMenu is the menu to be assigned.
* @param aMenu is the menu to be assigned.
* @param aTrigger determines conditions upon which the context menu is activated.
* @param aTrigger determines conditions upon which the context menu is activated.
*/
*/
void
SetContextMenu
(
CONTEXT_MENU
*
aMenu
,
CONTEXT_MENU_TRIGGER
aTrigger
=
CMENU_BUTTON
);
void
SetContextMenu
(
CONTEXT_MENU
*
aMenu
,
CONTEXT_MENU_TRIGGER
aTrigger
=
CMENU_BUTTON
);
/**
/**
* Function Go()
* Function Go()
*
*
* Defines which state (aStateFunc) to go when a certain event arrives (aConditions).
* Defines which state (aStateFunc) to go when a certain event arrives (aConditions).
* No conditions means any event.
* No conditions means any event.
*/
*/
template
<
class
T
>
template
<
class
T
>
void
Go
(
int
(
T
::*
aStateFunc
)(
TOOL_EVENT
&
),
void
Go
(
int
(
T
::*
aStateFunc
)(
TOOL_EVENT
&
),
const
TOOL_EVENT_LIST
&
aConditions
=
TOOL_EVENT
(
TC_Any
,
TA_Any
)
);
const
TOOL_EVENT_LIST
&
aConditions
=
TOOL_EVENT
(
TC_Any
,
TA_Any
)
);
/**
/**
* Function Wait()
* Function Wait()
*
*
* Suspends execution of the tool until an event specified in aEventList arrives.
* Suspends execution of the tool until an event specified in aEventList arrives.
* No parameters means waiting for any event.
* No parameters means waiting for any event.
*/
*/
OPT_TOOL_EVENT
Wait
(
const
TOOL_EVENT_LIST
&
aEventList
=
TOOL_EVENT
(
TC_Any
,
TA_Any
)
);
OPT_TOOL_EVENT
Wait
(
const
TOOL_EVENT_LIST
&
aEventList
=
TOOL_EVENT
(
TC_Any
,
TA_Any
)
);
/** functions below are not yet implemented - their interface may change */
/** functions below are not yet implemented - their interface may change */
/*template<class Parameters, class ReturnValue>
/*template<class Parameters, class ReturnValue>
bool InvokeTool( const std::string& aToolName, const Parameters& parameters,
bool InvokeTool( const std::string& aToolName, const Parameters& parameters,
ReturnValue& returnValue );
ReturnValue& returnValue );
template<class Parameters, class ReturnValue>
template<class Parameters, class ReturnValue>
bool InvokeWindow( const std::string& aWindowName, const Parameters& parameters,
bool InvokeWindow( const std::string& aWindowName, const Parameters& parameters,
ReturnValue& returnValue );
ReturnValue& returnValue );
template<class T>
template<class T>
void Yield( const T& returnValue );*/
void Yield( const T& returnValue );*/
protected
:
protected
:
/* helper functions for constructing events for Wait() and Go() with less typing */
/* helper functions for constructing events for Wait() and Go() with less typing */
const
TOOL_EVENT
evActivate
(
std
::
string
aToolName
=
""
);
const
TOOL_EVENT
evActivate
(
std
::
string
aToolName
=
""
);
const
TOOL_EVENT
evCommand
(
int
aCommandId
=
-
1
);
const
TOOL_EVENT
evCommand
(
int
aCommandId
=
-
1
);
const
TOOL_EVENT
evCommand
(
std
::
string
aCommandStr
=
""
);
const
TOOL_EVENT
evCommand
(
std
::
string
aCommandStr
=
""
);
const
TOOL_EVENT
evMotion
();
const
TOOL_EVENT
evMotion
();
const
TOOL_EVENT
evClick
(
int
aButton
=
MB_Any
);
const
TOOL_EVENT
evClick
(
int
aButton
=
MB_Any
);
const
TOOL_EVENT
evDrag
(
int
aButton
=
MB_Any
);
const
TOOL_EVENT
evDrag
(
int
aButton
=
MB_Any
);
const
TOOL_EVENT
evButtonUp
(
int
aButton
=
MB_Any
);
const
TOOL_EVENT
evButtonUp
(
int
aButton
=
MB_Any
);
const
TOOL_EVENT
evButtonDown
(
int
aButton
=
MB_Any
);
const
TOOL_EVENT
evButtonDown
(
int
aButton
=
MB_Any
);
private
:
private
:
void
goInternal
(
TOOL_STATE_FUNC
&
aState
,
const
TOOL_EVENT_LIST
&
aConditions
);
void
goInternal
(
TOOL_STATE_FUNC
&
aState
,
const
TOOL_EVENT_LIST
&
aConditions
);
};
};
// hide TOOL_MANAGER implementation
// hide TOOL_MANAGER implementation
...
@@ -125,8 +125,8 @@ template<class T>
...
@@ -125,8 +125,8 @@ template<class T>
void
TOOL_INTERACTIVE
::
Go
(
int
(
T
::*
aStateFunc
)(
TOOL_EVENT
&
),
void
TOOL_INTERACTIVE
::
Go
(
int
(
T
::*
aStateFunc
)(
TOOL_EVENT
&
),
const
TOOL_EVENT_LIST
&
aConditions
)
const
TOOL_EVENT_LIST
&
aConditions
)
{
{
TOOL_STATE_FUNC
sptr
(
static_cast
<
T
*>
(
this
),
aStateFunc
);
TOOL_STATE_FUNC
sptr
(
static_cast
<
T
*>
(
this
),
aStateFunc
);
goInternal
(
sptr
,
aConditions
);
goInternal
(
sptr
,
aConditions
);
}
}
#endif
#endif
include/view/view_controls.h
View file @
22045b61
...
@@ -122,7 +122,7 @@ public:
...
@@ -122,7 +122,7 @@ public:
virtual
const
VECTOR2D
GetCursorPosition
()
const
=
0
;
virtual
const
VECTOR2D
GetCursorPosition
()
const
=
0
;
/**
/**
* Function ForceCursorPosition()
* Function ForceCursorPosition()
* Places the cursor immediately at a given point. Mouse movement is ignored.
* Places the cursor immediately at a given point. Mouse movement is ignored.
* @param aEnabled enable forced cursor position
* @param aEnabled enable forced cursor position
...
...
pcbnew/edit.cpp
100755 → 100644
View file @
22045b61
File mode changed from 100755 to 100644
pcbnew/pcb_painter.cpp
View file @
22045b61
...
@@ -279,7 +279,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
...
@@ -279,7 +279,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
NETINFO_ITEM
*
net
=
(
(
BOARD
*
)
aTrack
->
GetParent
()
)
->
FindNet
(
netNumber
);
NETINFO_ITEM
*
net
=
(
(
BOARD
*
)
aTrack
->
GetParent
()
)
->
FindNet
(
netNumber
);
if
(
!
net
)
if
(
!
net
)
return
;
return
;
std
::
string
netName
=
std
::
string
(
net
->
GetShortNetname
().
mb_str
()
);
std
::
string
netName
=
std
::
string
(
net
->
GetShortNetname
().
mb_str
()
);
VECTOR2D
textPosition
=
start
+
line
/
2.0
;
// center of the track
VECTOR2D
textPosition
=
start
+
line
/
2.0
;
// center of the track
double
textOrientation
=
-
atan
(
line
.
y
/
line
.
x
);
double
textOrientation
=
-
atan
(
line
.
y
/
line
.
x
);
...
...
pcbnew/router/pns_itemset.h
View file @
22045b61
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
/**
/**
* Class PNS_ITEMSET
* Class PNS_ITEMSET
*
*
* Holds a list of board items, that can be filtered against net, kinds,
* Holds a list of board items, that can be filtered against net, kinds,
* layers, etc.
* layers, etc.
**/
**/
...
...
pcbnew/router/pns_joint.h
View file @
22045b61
...
@@ -32,9 +32,9 @@
...
@@ -32,9 +32,9 @@
/**
/**
* Class PNS_JOINT
* Class PNS_JOINT
*
*
* Represents a 2D point on a given set of layers and belonging to a certain
* Represents a 2D point on a given set of layers and belonging to a certain
* net, that links together a number of board items.
* net, that links together a number of board items.
* A hash table of joints is used by the router to follow connectivity between
* A hash table of joints is used by the router to follow connectivity between
* the items.
* the items.
**/
**/
class
PNS_JOINT
:
public
PNS_ITEM
class
PNS_JOINT
:
public
PNS_ITEM
...
@@ -53,8 +53,8 @@ public:
...
@@ -53,8 +53,8 @@ public:
PNS_JOINT
()
:
PNS_JOINT
()
:
PNS_ITEM
(
JOINT
)
{}
PNS_ITEM
(
JOINT
)
{}
PNS_JOINT
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
PNS_JOINT
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
=
-
1
)
:
int
aNet
=
-
1
)
:
PNS_ITEM
(
JOINT
)
PNS_ITEM
(
JOINT
)
{
{
m_tag
.
pos
=
aPos
;
m_tag
.
pos
=
aPos
;
...
@@ -78,14 +78,14 @@ public:
...
@@ -78,14 +78,14 @@ public:
return
NULL
;
return
NULL
;
}
}
///> Returns true if the joint is a trivial line corner, connecting two
///> Returns true if the joint is a trivial line corner, connecting two
/// segments of the same net, on the same layer.
/// segments of the same net, on the same layer.
bool
IsLineCorner
()
const
bool
IsLineCorner
()
const
{
{
if
(
m_linkedItems
.
size
()
!=
2
)
if
(
m_linkedItems
.
size
()
!=
2
)
return
false
;
return
false
;
if
(
m_linkedItems
[
0
]
->
GetKind
()
!=
SEGMENT
||
if
(
m_linkedItems
[
0
]
->
GetKind
()
!=
SEGMENT
||
m_linkedItems
[
1
]
->
GetKind
()
!=
SEGMENT
)
m_linkedItems
[
1
]
->
GetKind
()
!=
SEGMENT
)
return
false
;
return
false
;
...
@@ -99,7 +99,7 @@ public:
...
@@ -99,7 +99,7 @@ public:
///> Links the joint to a given board item (when it's added to the PNS_NODE)
///> Links the joint to a given board item (when it's added to the PNS_NODE)
void
Link
(
PNS_ITEM
*
aItem
)
void
Link
(
PNS_ITEM
*
aItem
)
{
{
LinkedItems
::
iterator
f
=
std
::
find
(
m_linkedItems
.
begin
(),
LinkedItems
::
iterator
f
=
std
::
find
(
m_linkedItems
.
begin
(),
m_linkedItems
.
end
(),
aItem
);
m_linkedItems
.
end
(),
aItem
);
if
(
f
!=
m_linkedItems
.
end
()
)
if
(
f
!=
m_linkedItems
.
end
()
)
...
@@ -112,7 +112,7 @@ public:
...
@@ -112,7 +112,7 @@ public:
///> Returns true if the joint became dangling after unlinking.
///> Returns true if the joint became dangling after unlinking.
bool
Unlink
(
PNS_ITEM
*
aItem
)
bool
Unlink
(
PNS_ITEM
*
aItem
)
{
{
LinkedItems
::
iterator
f
=
std
::
find
(
m_linkedItems
.
begin
(),
LinkedItems
::
iterator
f
=
std
::
find
(
m_linkedItems
.
begin
(),
m_linkedItems
.
end
(),
aItem
);
m_linkedItems
.
end
(),
aItem
);
if
(
f
!=
m_linkedItems
.
end
()
)
if
(
f
!=
m_linkedItems
.
end
()
)
...
@@ -142,7 +142,7 @@ public:
...
@@ -142,7 +142,7 @@ public:
{
{
int
n
=
0
;
int
n
=
0
;
for
(
LinkedItems
::
const_iterator
i
=
m_linkedItems
.
begin
();
for
(
LinkedItems
::
const_iterator
i
=
m_linkedItems
.
begin
();
i
!=
m_linkedItems
.
end
();
++
i
)
i
!=
m_linkedItems
.
end
();
++
i
)
if
(
(
*
i
)
->
GetKind
()
&
aMask
)
if
(
(
*
i
)
->
GetKind
()
&
aMask
)
n
++
;
n
++
;
...
@@ -172,7 +172,7 @@ public:
...
@@ -172,7 +172,7 @@ public:
bool
Overlaps
(
const
PNS_JOINT
&
rhs
)
const
bool
Overlaps
(
const
PNS_JOINT
&
rhs
)
const
{
{
return
m_tag
.
pos
==
rhs
.
m_tag
.
pos
&&
return
m_tag
.
pos
==
rhs
.
m_tag
.
pos
&&
m_tag
.
net
==
rhs
.
m_tag
.
net
&&
m_layers
.
Overlaps
(
rhs
.
m_layers
);
m_tag
.
net
==
rhs
.
m_tag
.
net
&&
m_layers
.
Overlaps
(
rhs
.
m_layers
);
}
}
...
@@ -186,7 +186,7 @@ private:
...
@@ -186,7 +186,7 @@ private:
// hash function & comparison operator for boost::unordered_map<>
// hash function & comparison operator for boost::unordered_map<>
inline
bool
operator
==
(
PNS_JOINT
::
HashTag
const
&
p1
,
inline
bool
operator
==
(
PNS_JOINT
::
HashTag
const
&
p1
,
PNS_JOINT
::
HashTag
const
&
p2
)
PNS_JOINT
::
HashTag
const
&
p2
)
{
{
return
p1
.
pos
==
p2
.
pos
&&
p1
.
net
==
p2
.
net
;
return
p1
.
pos
==
p2
.
pos
&&
p1
.
net
==
p2
.
net
;
...
...
pcbnew/router/pns_line.cpp
View file @
22045b61
...
@@ -434,7 +434,7 @@ void PNS_LINE::NewWalkaround( const SHAPE_LINE_CHAIN& aObstacle,
...
@@ -434,7 +434,7 @@ void PNS_LINE::NewWalkaround( const SHAPE_LINE_CHAIN& aObstacle,
path
.
Append
(
l_hull
.
CPoint
(
j
)
);
path
.
Append
(
l_hull
.
CPoint
(
j
)
);
li
=
l_orig
.
Find
(
l_hull
.
CPoint
(
j
)
);
li
=
l_orig
.
Find
(
l_hull
.
CPoint
(
j
)
);
if
(
li
>=
0
&&
(
li
==
(
l_orig
.
PointCount
()
-
1
)
||
if
(
li
>=
0
&&
(
li
==
(
l_orig
.
PointCount
()
-
1
)
||
outside
[
li
+
1
])
)
outside
[
li
+
1
])
)
break
;
break
;
}
}
...
@@ -514,7 +514,7 @@ bool PNS_LINE::walkScan( const SHAPE_LINE_CHAIN& line,
...
@@ -514,7 +514,7 @@ bool PNS_LINE::walkScan( const SHAPE_LINE_CHAIN& line,
{
{
index_l
=
(
reverse
?
sc
-
1
-
i
:
i
);
index_l
=
(
reverse
?
sc
-
1
-
i
:
i
);
ip
=
s
.
a
;
ip
=
s
.
a
;
printf
(
"vertex %d on-%s %d
\n
"
,
index_l
,
printf
(
"vertex %d on-%s %d
\n
"
,
index_l
,
is_vertex
?
"vertex"
:
"edge"
,
index_o
);
is_vertex
?
"vertex"
:
"edge"
,
index_o
);
return
true
;
return
true
;
}
}
...
@@ -523,7 +523,7 @@ bool PNS_LINE::walkScan( const SHAPE_LINE_CHAIN& line,
...
@@ -523,7 +523,7 @@ bool PNS_LINE::walkScan( const SHAPE_LINE_CHAIN& line,
{
{
index_l
=
(
reverse
?
sc
-
1
-
i
-
1
:
i
+
1
);
index_l
=
(
reverse
?
sc
-
1
-
i
-
1
:
i
+
1
);
ip
=
s
.
b
;
ip
=
s
.
b
;
printf
(
"vertex %d on-%s %d
\n
"
,
index_l
,
printf
(
"vertex %d on-%s %d
\n
"
,
index_l
,
is_vertex
?
"vertex"
:
"edge"
,
index_o
);
is_vertex
?
"vertex"
:
"edge"
,
index_o
);
return
true
;
return
true
;
}
}
...
@@ -562,7 +562,7 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN obstacle,
...
@@ -562,7 +562,7 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN obstacle,
if
(
line
.
SegmentCount
()
<
1
)
if
(
line
.
SegmentCount
()
<
1
)
return
false
;
return
false
;
if
(
obstacle
.
PointInside
(
line
.
CPoint
(
0
)
)
||
if
(
obstacle
.
PointInside
(
line
.
CPoint
(
0
)
)
||
obstacle
.
PointInside
(
line
.
CPoint
(
-
1
)
)
)
obstacle
.
PointInside
(
line
.
CPoint
(
-
1
)
)
)
return
false
;
return
false
;
...
@@ -714,7 +714,7 @@ bool PNS_LINE::Is45Degree()
...
@@ -714,7 +714,7 @@ bool PNS_LINE::Is45Degree()
const
SEG
&
s
=
m_line
.
CSegment
(
i
);
const
SEG
&
s
=
m_line
.
CSegment
(
i
);
double
angle
=
180.0
/
M_PI
*
double
angle
=
180.0
/
M_PI
*
atan2
(
(
double
)
s
.
b
.
y
-
(
double
)
s
.
a
.
y
,
atan2
(
(
double
)
s
.
b
.
y
-
(
double
)
s
.
a
.
y
,
(
double
)
s
.
b
.
x
-
(
double
)
s
.
a
.
x
);
(
double
)
s
.
b
.
x
-
(
double
)
s
.
a
.
x
);
if
(
angle
<
0
)
if
(
angle
<
0
)
...
...
pcbnew/router/pns_line.h
View file @
22045b61
...
@@ -38,17 +38,17 @@ class PNS_VIA;
...
@@ -38,17 +38,17 @@ class PNS_VIA;
/**
/**
* Class PNS_LINE
* Class PNS_LINE
*
*
* Represents a track on a PCB, connecting two non-trivial joints (that is,
* Represents a track on a PCB, connecting two non-trivial joints (that is,
* vias, pads, junctions between multiple traces or two traces different widths
* vias, pads, junctions between multiple traces or two traces different widths
* and combinations of these). PNS_LINEs are NOT stored in the model (PNS_NODE).
* and combinations of these). PNS_LINEs are NOT stored in the model (PNS_NODE).
* Instead, they are assembled on-the-fly, based on a via/pad/segment that
* Instead, they are assembled on-the-fly, based on a via/pad/segment that
* belongs/begins them.
* belongs/begins them.
*
*
* PNS_LINEs can be either loose (consisting of segments that do not belong to
* PNS_LINEs can be either loose (consisting of segments that do not belong to
* any PNS_NODE) or owned (with segments taken from a PNS_NODE) - these are
* any PNS_NODE) or owned (with segments taken from a PNS_NODE) - these are
* returned by PNS_NODE::AssembleLine and friends.
* returned by PNS_NODE::AssembleLine and friends.
*
*
* A PNS_LINE may have a PNS_VIA attached at its and - this is used by via
* A PNS_LINE may have a PNS_VIA attached at its and - this is used by via
* dragging/force propagation stuff.
* dragging/force propagation stuff.
*/
*/
...
@@ -141,7 +141,7 @@ public:
...
@@ -141,7 +141,7 @@ public:
m_segmentRefs
->
push_back
(
aSeg
);
m_segmentRefs
->
push_back
(
aSeg
);
}
}
///> Returns a list of segments from the owning node that constitute this
///> Returns a list of segments from the owning node that constitute this
///> line (or NULL if the line is loose)
///> line (or NULL if the line is loose)
LinkedSegments
*
GetLinkedSegments
()
LinkedSegments
*
GetLinkedSegments
()
{
{
...
@@ -157,7 +157,7 @@ public:
...
@@ -157,7 +157,7 @@ public:
aSeg
)
!=
m_segmentRefs
->
end
();
aSeg
)
!=
m_segmentRefs
->
end
();
}
}
///> Returns this line, but clipped to the nearest obstacle
///> Returns this line, but clipped to the nearest obstacle
///> along, to avoid collision.
///> along, to avoid collision.
const
PNS_LINE
ClipToNearestObstacle
(
PNS_NODE
*
aNode
)
const
;
const
PNS_LINE
ClipToNearestObstacle
(
PNS_NODE
*
aNode
)
const
;
...
@@ -168,7 +168,7 @@ public:
...
@@ -168,7 +168,7 @@ public:
///> Returns the number of corners of angles specified by mask aAngles.
///> Returns the number of corners of angles specified by mask aAngles.
int
CountCorners
(
int
aAngles
);
int
CountCorners
(
int
aAngles
);
///> Calculates a line thightly wrapping a convex hull
///> Calculates a line thightly wrapping a convex hull
///> of an obstacle object (aObstacle).
///> of an obstacle object (aObstacle).
///> aPrePath = path from origin to the obstacle
///> aPrePath = path from origin to the obstacle
///> aWalkaroundPath = path around the obstacle
///> aWalkaroundPath = path around the obstacle
...
...
pcbnew/router/pns_line_placer.cpp
View file @
22045b61
...
@@ -63,7 +63,7 @@ void PNS_LINE_PLACER::ApplySettings( const PNS_ROUTING_SETTINGS& aSettings )
...
@@ -63,7 +63,7 @@ void PNS_LINE_PLACER::ApplySettings( const PNS_ROUTING_SETTINGS& aSettings )
}
}
void
PNS_LINE_PLACER
::
StartPlacement
(
const
VECTOR2I
&
aStart
,
int
aNet
,
void
PNS_LINE_PLACER
::
StartPlacement
(
const
VECTOR2I
&
aStart
,
int
aNet
,
int
aWidth
,
int
aLayer
)
int
aWidth
,
int
aLayer
)
{
{
m_direction
=
m_initial_direction
;
m_direction
=
m_initial_direction
;
...
@@ -177,14 +177,14 @@ bool PNS_LINE_PLACER::handlePullback()
...
@@ -177,14 +177,14 @@ bool PNS_LINE_PLACER::handlePullback()
DIRECTION_45
last_tail
(
tail
.
Segment
(
-
1
)
);
DIRECTION_45
last_tail
(
tail
.
Segment
(
-
1
)
);
DIRECTION_45
::
AngleType
angle
=
first_head
.
Angle
(
last_tail
);
DIRECTION_45
::
AngleType
angle
=
first_head
.
Angle
(
last_tail
);
// case 1: we have a defined routing direction, and the currently computed
// case 1: we have a defined routing direction, and the currently computed
// head goes in different one.
// head goes in different one.
bool
pullback_1
=
false
;
// (m_direction != DIRECTION_45::UNDEFINED && m_direction != first_head);
bool
pullback_1
=
false
;
// (m_direction != DIRECTION_45::UNDEFINED && m_direction != first_head);
// case 2: regardless of the current routing direction, if the tail/head
// case 2: regardless of the current routing direction, if the tail/head
// extremities form an acute or right angle, reduce the tail by one segment
// extremities form an acute or right angle, reduce the tail by one segment
// (and hope that further iterations) will result with a cleaner trace
// (and hope that further iterations) will result with a cleaner trace
bool
pullback_2
=
(
angle
==
DIRECTION_45
::
ANG_RIGHT
||
bool
pullback_2
=
(
angle
==
DIRECTION_45
::
ANG_RIGHT
||
angle
==
DIRECTION_45
::
ANG_ACUTE
);
angle
==
DIRECTION_45
::
ANG_ACUTE
);
if
(
pullback_1
||
pullback_2
)
if
(
pullback_1
||
pullback_2
)
...
@@ -197,7 +197,7 @@ bool PNS_LINE_PLACER::handlePullback()
...
@@ -197,7 +197,7 @@ bool PNS_LINE_PLACER::handlePullback()
n
%
last_tail
.
Format
().
c_str
()
%
first_head
.
Format
().
c_str
()
);
n
%
last_tail
.
Format
().
c_str
()
%
first_head
.
Format
().
c_str
()
);
// erase the last point in the tail, hoping that the next iteration will
// erase the last point in the tail, hoping that the next iteration will
// result with a head trace that starts with a segment following our
// result with a head trace that starts with a segment following our
// current direction.
// current direction.
if
(
n
<
2
)
if
(
n
<
2
)
tail
.
Clear
();
// don't leave a single-point tail
tail
.
Clear
();
// don't leave a single-point tail
...
@@ -239,7 +239,7 @@ bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd )
...
@@ -239,7 +239,7 @@ bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd )
const
SEG
s
=
tail
.
CSegment
(
i
);
const
SEG
s
=
tail
.
CSegment
(
i
);
DIRECTION_45
dir
(
s
);
DIRECTION_45
dir
(
s
);
// calculate a replacement route and check if it matches
// calculate a replacement route and check if it matches
// the direction of the segment to be replaced
// the direction of the segment to be replaced
SHAPE_LINE_CHAIN
replacement
=
dir
.
BuildInitialTrace
(
s
.
a
,
aEnd
);
SHAPE_LINE_CHAIN
replacement
=
dir
.
BuildInitialTrace
(
s
.
a
,
aEnd
);
...
@@ -289,7 +289,7 @@ bool PNS_LINE_PLACER::mergeHead()
...
@@ -289,7 +289,7 @@ bool PNS_LINE_PLACER::mergeHead()
SHAPE_LINE_CHAIN
&
head
=
m_head
.
GetLine
();
SHAPE_LINE_CHAIN
&
head
=
m_head
.
GetLine
();
SHAPE_LINE_CHAIN
&
tail
=
m_tail
.
GetLine
();
SHAPE_LINE_CHAIN
&
tail
=
m_tail
.
GetLine
();
const
int
ForbiddenAngles
=
DIRECTION_45
::
ANG_ACUTE
|
const
int
ForbiddenAngles
=
DIRECTION_45
::
ANG_ACUTE
|
DIRECTION_45
::
ANG_HALF_FULL
|
DIRECTION_45
::
ANG_HALF_FULL
|
DIRECTION_45
::
ANG_UNDEFINED
;
DIRECTION_45
::
ANG_UNDEFINED
;
...
@@ -366,7 +366,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
...
@@ -366,7 +366,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
if
(
v
.
PushoutForce
(
m_shove
->
GetCurrentNode
(),
lead
,
force
,
true
,
20
)
)
if
(
v
.
PushoutForce
(
m_shove
->
GetCurrentNode
(),
lead
,
force
,
true
,
20
)
)
{
{
SHAPE_LINE_CHAIN
line
=
m_direction
.
BuildInitialTrace
(
SHAPE_LINE_CHAIN
line
=
m_direction
.
BuildInitialTrace
(
aHead
.
GetCLine
().
CPoint
(
0
),
aHead
.
GetCLine
().
CPoint
(
0
),
aHead
.
GetCLine
().
CPoint
(
-
1
)
+
force
);
aHead
.
GetCLine
().
CPoint
(
-
1
)
+
force
);
aHead
=
PNS_LINE
(
aHead
,
line
);
aHead
=
PNS_LINE
(
aHead
,
line
);
...
@@ -379,7 +379,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
...
@@ -379,7 +379,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
}
}
bool
PNS_LINE_PLACER
::
routeHead
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
,
bool
PNS_LINE_PLACER
::
routeHead
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
,
bool
aCwWalkaround
)
bool
aCwWalkaround
)
{
{
// STAGE 1: route a simple two-segment trace between m_p_start and aP...
// STAGE 1: route a simple two-segment trace between m_p_start and aP...
...
@@ -543,7 +543,7 @@ bool PNS_LINE_PLACER::optimizeTailHeadTransition()
...
@@ -543,7 +543,7 @@ bool PNS_LINE_PLACER::optimizeTailHeadTransition()
PNS_LINE
new_head
(
m_tail
,
opt_line
);
PNS_LINE
new_head
(
m_tail
,
opt_line
);
// and see if it could be made simpler by merging obtuse/collnear segments.
// and see if it could be made simpler by merging obtuse/collnear segments.
// If so, replace the (threshold) last tail points and the head with
// If so, replace the (threshold) last tail points and the head with
// the optimized line
// the optimized line
// if(PNS_OPTIMIZER::Optimize(&new_head, PNS_OPTIMIZER::MERGE_SEGMENTS))
// if(PNS_OPTIMIZER::Optimize(&new_head, PNS_OPTIMIZER::MERGE_SEGMENTS))
...
...
pcbnew/router/pns_line_placer.h
View file @
22045b61
...
@@ -39,7 +39,7 @@ class PNS_ROUTER_BASE;
...
@@ -39,7 +39,7 @@ class PNS_ROUTER_BASE;
/**
/**
* Class PNS_LINE_PLACER
* Class PNS_LINE_PLACER
*
*
* Interactively routes a single track. Runs shove and walkaround
* Interactively routes a single track. Runs shove and walkaround
* algorithms when needed.
* algorithms when needed.
*/
*/
...
@@ -63,9 +63,9 @@ public:
...
@@ -63,9 +63,9 @@ public:
/**
/**
* Function Route()
* Function Route()
*
*
* Re-routes the current track to point aP. Returns true, when routing has
* Re-routes the current track to point aP. Returns true, when routing has
* completed successfully (i.e. the trace end has reached point aP), and false
* completed successfully (i.e. the trace end has reached point aP), and false
* if the trace was stuck somewhere on the way. May call routeStep()
* if the trace was stuck somewhere on the way. May call routeStep()
* repetitively due to mouse smoothing.
* repetitively due to mouse smoothing.
* @param aP ending point of current route.
* @param aP ending point of current route.
* @return true, if the routing is complete.
* @return true, if the routing is complete.
...
@@ -80,7 +80,7 @@ public:
...
@@ -80,7 +80,7 @@ public:
///> Returns the "head" of the line being placed, that is the volatile part
///> Returns the "head" of the line being placed, that is the volatile part
///> that has not been settled yet
///> that has not been settled yet
const
PNS_LINE
&
GetHead
()
const
{
return
m_head
;
}
const
PNS_LINE
&
GetHead
()
const
{
return
m_head
;
}
///> Returns the "tail" of the line being placed the part that has been
///> Returns the "tail" of the line being placed the part that has been
///> fixed already (follow mouse mode only)
///> fixed already (follow mouse mode only)
const
PNS_LINE
&
GetTail
()
const
{
return
m_tail
;
}
const
PNS_LINE
&
GetTail
()
const
{
return
m_tail
;
}
...
@@ -99,9 +99,9 @@ public:
...
@@ -99,9 +99,9 @@ public:
return
m_p_start
;
return
m_p_start
;
}
}
///> Returns all items in the world that have been affected by the routing
///> Returns all items in the world that have been affected by the routing
///> operation. Used to update data structures of the host application
///> operation. Used to update data structures of the host application
void
GetUpdatedItems
(
PNS_NODE
::
ItemVector
&
aRemoved
,
void
GetUpdatedItems
(
PNS_NODE
::
ItemVector
&
aRemoved
,
PNS_NODE
::
ItemVector
&
aAdded
);
PNS_NODE
::
ItemVector
&
aAdded
);
///> Toggles the current posture (straight/diagonal) of the trace head.
///> Toggles the current posture (straight/diagonal) of the trace head.
...
@@ -114,30 +114,30 @@ private:
...
@@ -114,30 +114,30 @@ private:
static
const
double
m_shoveLengthThreshold
=
1
.
7
;
static
const
double
m_shoveLengthThreshold
=
1
.
7
;
bool
handleViaPlacement
(
PNS_LINE
&
aHead
);
bool
handleViaPlacement
(
PNS_LINE
&
aHead
);
/**
/**
* Function checkObtusity()
* Function checkObtusity()
*
*
* Helper that checks if segments a and b form an obtuse angle
* Helper that checks if segments a and b form an obtuse angle
* (in 45-degree regime).
* (in 45-degree regime).
* @return true, if angle (a, b) is obtuse
* @return true, if angle (a, b) is obtuse
*/
*/
bool
checkObtusity
(
const
SEG
&
a
,
const
SEG
&
b
)
const
;
bool
checkObtusity
(
const
SEG
&
a
,
const
SEG
&
b
)
const
;
/**
/**
* Function handleSelfIntersections()
* Function handleSelfIntersections()
*
*
* Checks if the head of the track intersects its tail. If so, cuts the
* Checks if the head of the track intersects its tail. If so, cuts the
* tail up to the intersecting segment and fixes the head direction to match
* tail up to the intersecting segment and fixes the head direction to match
* the last segment before the cut.
* the last segment before the cut.
* @return true if the line has been changed.
* @return true if the line has been changed.
*/
*/
bool
handleSelfIntersections
();
bool
handleSelfIntersections
();
/**
/**
* Function handlePullback()
* Function handlePullback()
*
*
* Deals with pull-back: reduces the tail if head trace is moved backwards
* Deals with pull-back: reduces the tail if head trace is moved backwards
* wrs to the current tail direction.
* wrs to the current tail direction.
* @return true if the line has been changed.
* @return true if the line has been changed.
*/
*/
...
@@ -146,7 +146,7 @@ private:
...
@@ -146,7 +146,7 @@ private:
/**
/**
* Function mergeHead()
* Function mergeHead()
*
*
* Moves "estabished" segments from the head to the tail if certain
* Moves "estabished" segments from the head to the tail if certain
* conditions are met.
* conditions are met.
* @return true, if the line has been changed.
* @return true, if the line has been changed.
*/
*/
...
@@ -155,20 +155,20 @@ private:
...
@@ -155,20 +155,20 @@ private:
/**
/**
* Function reduceTail()
* Function reduceTail()
*
*
* Attempts to reduce the numer of segments in the tail by trying to replace a
* Attempts to reduce the numer of segments in the tail by trying to replace a
* certain number of latest tail segments with a direct trace leading to aEnd
* certain number of latest tail segments with a direct trace leading to aEnd
* that does not collide with anything.
* that does not collide with anything.
* @param aEnd: current routing destination point.
* @param aEnd: current routing destination point.
* @return true if the line has been changed.
* @return true if the line has been changed.
*/
*/
bool
reduceTail
(
const
VECTOR2I
&
aEnd
);
bool
reduceTail
(
const
VECTOR2I
&
aEnd
);
void
fixHeadPosture
();
void
fixHeadPosture
();
/**
/**
* Function optimizeTailHeadTransition()
* Function optimizeTailHeadTransition()
*
*
* Tries to reduce the corner count of the most recent part of tail/head by
* Tries to reduce the corner count of the most recent part of tail/head by
* merging obtuse/collinear segments.
* merging obtuse/collinear segments.
* @return true, if the line has been changed.
* @return true, if the line has been changed.
*/
*/
...
@@ -177,12 +177,12 @@ private:
...
@@ -177,12 +177,12 @@ private:
/**
/**
* Function routeHead()
* Function routeHead()
*
*
* Computes the head trace between the current start point (m_p_start) and
* Computes the head trace between the current start point (m_p_start) and
* point aP, starting with direction defined in m_direction. The trace walks
* point aP, starting with direction defined in m_direction. The trace walks
* around all colliding solid or non-movable items. Movable segments are
* around all colliding solid or non-movable items. Movable segments are
* ignored, as they'll be handled later by the shove algorithm.
* ignored, as they'll be handled later by the shove algorithm.
*/
*/
bool
routeHead
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
,
bool
routeHead
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
,
bool
aCwWalkaround
=
true
);
bool
aCwWalkaround
=
true
);
/**
/**
...
@@ -197,7 +197,7 @@ private:
...
@@ -197,7 +197,7 @@ private:
///> routing mode (walkaround, shove, etc.)
///> routing mode (walkaround, shove, etc.)
PNS_MODE
m_mode
;
PNS_MODE
m_mode
;
///> follow mouse trail by attaching new segments to the head
///> follow mouse trail by attaching new segments to the head
///> as the cursor moves
///> as the cursor moves
bool
m_follow_mouse
;
bool
m_follow_mouse
;
...
...
pcbnew/router/pns_node.cpp
View file @
22045b61
...
@@ -71,7 +71,7 @@ PNS_NODE::~PNS_NODE()
...
@@ -71,7 +71,7 @@ PNS_NODE::~PNS_NODE()
allocNodes
.
erase
(
this
);
allocNodes
.
erase
(
this
);
for
(
PNS_INDEX
::
ItemSet
::
iterator
i
=
m_index
->
begin
();
for
(
PNS_INDEX
::
ItemSet
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
i
!=
m_index
->
end
();
++
i
)
if
(
(
*
i
)
->
BelongsTo
(
this
)
)
if
(
(
*
i
)
->
BelongsTo
(
this
)
)
delete
*
i
;
delete
*
i
;
...
@@ -111,14 +111,14 @@ PNS_NODE* PNS_NODE::Branch()
...
@@ -111,14 +111,14 @@ PNS_NODE* PNS_NODE::Branch()
child
->
m_clearanceFunctor
=
m_clearanceFunctor
;
child
->
m_clearanceFunctor
=
m_clearanceFunctor
;
child
->
m_root
=
isRoot
()
?
this
:
m_root
;
child
->
m_root
=
isRoot
()
?
this
:
m_root
;
// immmediate offspring of the root branch needs not copy anything.
// immmediate offspring of the root branch needs not copy anything.
// For the rest, deep-copy joints, overridden item map and pointers
// For the rest, deep-copy joints, overridden item map and pointers
// to stored items.
// to stored items.
if
(
!
isRoot
()
)
if
(
!
isRoot
()
)
{
{
JointMap
::
iterator
j
;
JointMap
::
iterator
j
;
for
(
PNS_INDEX
::
ItemSet
::
iterator
i
=
m_index
->
begin
();
for
(
PNS_INDEX
::
ItemSet
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
i
!=
m_index
->
end
();
++
i
)
child
->
m_index
->
Add
(
*
i
);
child
->
m_index
->
Add
(
*
i
);
...
@@ -150,7 +150,7 @@ void PNS_NODE::unlinkParent()
...
@@ -150,7 +150,7 @@ void PNS_NODE::unlinkParent()
}
}
// function object that visits potential obstacles and performs
// function object that visits potential obstacles and performs
// the actual collision refining
// the actual collision refining
struct
PNS_NODE
::
obstacleVisitor
struct
PNS_NODE
::
obstacleVisitor
{
{
...
@@ -200,7 +200,7 @@ struct PNS_NODE::obstacleVisitor
...
@@ -200,7 +200,7 @@ struct PNS_NODE::obstacleVisitor
if
(
!
aItem
->
OfKind
(
m_kindMask
)
)
if
(
!
aItem
->
OfKind
(
m_kindMask
)
)
return
true
;
return
true
;
// check if there is a more recent branch with a newer
// check if there is a more recent branch with a newer
// (possibily modified) version of this item.
// (possibily modified) version of this item.
if
(
m_override
&&
m_override
->
overrides
(
aItem
)
)
if
(
m_override
&&
m_override
->
overrides
(
aItem
)
)
return
true
;
return
true
;
...
@@ -428,8 +428,8 @@ struct hitVisitor
...
@@ -428,8 +428,8 @@ struct hitVisitor
const
PNS_ITEMSET
PNS_NODE
::
HitTest
(
const
VECTOR2I
&
aPoint
)
const
PNS_ITEMSET
PNS_NODE
::
HitTest
(
const
VECTOR2I
&
aPoint
)
{
{
PNS_ITEMSET
items
;
PNS_ITEMSET
items
;
// fixme: we treat a point as an infinitely small circle - this is inefficient.
// fixme: we treat a point as an infinitely small circle - this is inefficient.
SHAPE_CIRCLE
s
(
aPoint
,
0
);
SHAPE_CIRCLE
s
(
aPoint
,
0
);
hitVisitor
visitor
(
items
,
aPoint
,
this
);
hitVisitor
visitor
(
items
,
aPoint
,
this
);
m_index
->
Query
(
&
s
,
m_maxClearance
,
visitor
);
m_index
->
Query
(
&
s
,
m_maxClearance
,
visitor
);
...
@@ -537,12 +537,12 @@ void PNS_NODE::Add( PNS_ITEM* aItem )
...
@@ -537,12 +537,12 @@ void PNS_NODE::Add( PNS_ITEM* aItem )
void
PNS_NODE
::
doRemove
(
PNS_ITEM
*
aItem
)
void
PNS_NODE
::
doRemove
(
PNS_ITEM
*
aItem
)
{
{
// case 1: removing an item that is stored in the root node from any branch:
// case 1: removing an item that is stored in the root node from any branch:
// mark it as overridden, but do not remove
// mark it as overridden, but do not remove
if
(
aItem
->
BelongsTo
(
m_root
)
&&
!
isRoot
()
)
if
(
aItem
->
BelongsTo
(
m_root
)
&&
!
isRoot
()
)
m_override
.
insert
(
aItem
);
m_override
.
insert
(
aItem
);
// case 2: the item belongs to this branch or a parent, non-root branch,
// case 2: the item belongs to this branch or a parent, non-root branch,
// or the root itself and we are the root: remove from the index
// or the root itself and we are the root: remove from the index
else
if
(
!
aItem
->
BelongsTo
(
m_root
)
||
isRoot
()
)
else
if
(
!
aItem
->
BelongsTo
(
m_root
)
||
isRoot
()
)
m_index
->
Remove
(
aItem
);
m_index
->
Remove
(
aItem
);
...
@@ -948,7 +948,7 @@ void PNS_NODE::Commit( PNS_NODE* aNode )
...
@@ -948,7 +948,7 @@ void PNS_NODE::Commit( PNS_NODE* aNode )
BOOST_FOREACH
(
PNS_ITEM
*
item
,
aNode
->
m_override
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
aNode
->
m_override
)
Remove
(
item
);
Remove
(
item
);
for
(
PNS_INDEX
::
ItemSet
::
iterator
i
=
aNode
->
m_index
->
begin
();
for
(
PNS_INDEX
::
ItemSet
::
iterator
i
=
aNode
->
m_index
->
begin
();
i
!=
aNode
->
m_index
->
end
();
++
i
)
i
!=
aNode
->
m_index
->
end
();
++
i
)
Add
(
*
i
);
Add
(
*
i
);
...
...
pcbnew/router/pns_node.h
View file @
22045b61
...
@@ -79,13 +79,13 @@ struct PNS_OBSTACLE
...
@@ -79,13 +79,13 @@ struct PNS_OBSTACLE
/**
/**
* Class PNS_NODE
* Class PNS_NODE
*
*
* Keeps the router "world" - i.e. all the tracks, vias, solids in a
* Keeps the router "world" - i.e. all the tracks, vias, solids in a
* hierarchical and indexed way.
* hierarchical and indexed way.
* Features:
* Features:
* - spatial-indexed container for PCB item shapes
* - spatial-indexed container for PCB item shapes
* - collision search (with clearance checking)
* - collision search (with clearance checking)
* - assembly of lines connecting joints, finding loops and unique paths
* - assembly of lines connecting joints, finding loops and unique paths
* - lightweight cloning/branching (for recursive optimization and shove
* - lightweight cloning/branching (for recursive optimization and shove
* springback)
* springback)
**/
**/
...
@@ -145,11 +145,11 @@ public:
...
@@ -145,11 +145,11 @@ public:
void
Remove
(
PNS_ITEM
*
aItem
);
void
Remove
(
PNS_ITEM
*
aItem
);
void
Replace
(
PNS_ITEM
*
aOldItem
,
PNS_ITEM
*
aNewItem
);
void
Replace
(
PNS_ITEM
*
aOldItem
,
PNS_ITEM
*
aNewItem
);
///> Creates a lightweight copy ("branch") of self. Note that if there are
///> Creates a lightweight copy ("branch") of self. Note that if there are
///> any branches in use, their parents must NOT be deleted.
///> any branches in use, their parents must NOT be deleted.
PNS_NODE
*
Branch
();
PNS_NODE
*
Branch
();
///> Assembles a line connecting two non-trivial joints the
///> Assembles a line connecting two non-trivial joints the
///> segment aSeg belongs to.
///> segment aSeg belongs to.
PNS_LINE
*
AssembleLine
(
PNS_SEGMENT
*
aSeg
,
PNS_LINE
*
AssembleLine
(
PNS_SEGMENT
*
aSeg
,
const
OptJoint
&
a
=
OptJoint
(),
const
OptJoint
&
b
=
OptJoint
()
);
const
OptJoint
&
a
=
OptJoint
(),
const
OptJoint
&
b
=
OptJoint
()
);
...
@@ -175,15 +175,15 @@ public:
...
@@ -175,15 +175,15 @@ public:
const
OptJoint
FindJoint
(
const
VECTOR2I
&
aPos
,
int
aLayer
,
int
aNet
);
const
OptJoint
FindJoint
(
const
VECTOR2I
&
aPos
,
int
aLayer
,
int
aNet
);
///> finds all linest between a pair of joints. Used by the loop removal engine.
///> finds all linest between a pair of joints. Used by the loop removal engine.
int
FindLinesBetweenJoints
(
PNS_JOINT
&
a
,
PNS_JOINT
&
b
,
int
FindLinesBetweenJoints
(
PNS_JOINT
&
a
,
PNS_JOINT
&
b
,
std
::
vector
<
PNS_LINE
*>&
aLines
);
std
::
vector
<
PNS_LINE
*>&
aLines
);
///> finds the joints corresponding to the ends of line aLine
///> finds the joints corresponding to the ends of line aLine
void
FindLineEnds
(
PNS_LINE
*
aLine
,
PNS_JOINT
&
a
,
PNS_JOINT
&
b
);
void
FindLineEnds
(
PNS_LINE
*
aLine
,
PNS_JOINT
&
a
,
PNS_JOINT
&
b
);
///> finds all joints that have an (in)direct connection(s)
///> finds all joints that have an (in)direct connection(s)
///> (i.e. segments/vias) with the joint aJoint.
///> (i.e. segments/vias) with the joint aJoint.
void
FindConnectedJoints
(
const
PNS_JOINT
&
aJoint
,
void
FindConnectedJoints
(
const
PNS_JOINT
&
aJoint
,
std
::
vector
<
PNS_JOINT
*>&
aConnectedJoints
);
std
::
vector
<
PNS_JOINT
*>&
aConnectedJoints
);
///> Destroys all child nodes. Applicable only to the root node.
///> Destroys all child nodes. Applicable only to the root node.
...
@@ -201,15 +201,15 @@ private:
...
@@ -201,15 +201,15 @@ private:
PNS_NODE
&
operator
=
(
const
PNS_NODE
&
b
);
PNS_NODE
&
operator
=
(
const
PNS_NODE
&
b
);
///> tries to find matching joint and creates a new one if not found
///> tries to find matching joint and creates a new one if not found
PNS_JOINT
&
touchJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
PNS_JOINT
&
touchJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
);
int
aNet
);
///> touches a joint and links it to an item
///> touches a joint and links it to an item
void
linkJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
void
linkJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
,
PNS_ITEM
*
aWhere
);
int
aNet
,
PNS_ITEM
*
aWhere
);
///> unlinks an item from a joint
///> unlinks an item from a joint
void
unlinkJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
void
unlinkJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
,
PNS_ITEM
*
aWhere
);
int
aNet
,
PNS_ITEM
*
aWhere
);
///> helpers for adding/removing items
///> helpers for adding/removing items
...
@@ -231,7 +231,7 @@ private:
...
@@ -231,7 +231,7 @@ private:
return
m_parent
==
NULL
;
return
m_parent
==
NULL
;
}
}
///> checks if this branch contains an updated version of the item
///> checks if this branch contains an updated version of the item
///> from the root branch.
///> from the root branch.
bool
overrides
(
PNS_ITEM
*
aItem
)
const
bool
overrides
(
PNS_ITEM
*
aItem
)
const
{
{
...
@@ -249,7 +249,7 @@ private:
...
@@ -249,7 +249,7 @@ private:
///> spatial index of all items
///> spatial index of all items
// SHAPE_INDEX_LIST<PNS_ITEM *> m_items;
// SHAPE_INDEX_LIST<PNS_ITEM *> m_items;
///> hash table with the joints, linking the items. Joints are hashed by
///> hash table with the joints, linking the items. Joints are hashed by
///> their position, layer set and net.
///> their position, layer set and net.
JointMap
m_joints
;
JointMap
m_joints
;
...
...
pcbnew/router/pns_optimizer.cpp
View file @
22045b61
...
@@ -109,7 +109,7 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
...
@@ -109,7 +109,7 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
{
{
if
(
aOther
.
m_cornerCost
<
m_cornerCost
&&
aOther
.
m_lengthCost
<
m_lengthCost
)
if
(
aOther
.
m_cornerCost
<
m_cornerCost
&&
aOther
.
m_lengthCost
<
m_lengthCost
)
return
true
;
return
true
;
else
if
(
aOther
.
m_cornerCost
<
m_cornerCost
*
aCornerTollerance
&&
aOther
.
m_lengthCost
<
else
if
(
aOther
.
m_cornerCost
<
m_cornerCost
*
aCornerTollerance
&&
aOther
.
m_lengthCost
<
m_lengthCost
*
aLengthTollerance
)
m_lengthCost
*
aLengthTollerance
)
return
true
;
return
true
;
...
@@ -531,19 +531,19 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth,
...
@@ -531,19 +531,19 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth,
if
(
s
.
x
>=
s
.
y
)
if
(
s
.
x
>=
s
.
y
)
{
{
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
+
d_offset
,
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
+
d_offset
,
c
+
d_offset
+
VECTOR2I
(
l
,
l
)
)
);
c
+
d_offset
+
VECTOR2I
(
l
,
l
)
)
);
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
+
d_offset
,
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
+
d_offset
,
c
+
d_offset
-
VECTOR2I
(
-
l
,
l
)
)
);
c
+
d_offset
-
VECTOR2I
(
-
l
,
l
)
)
);
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
-
d_offset
,
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
-
d_offset
,
c
-
d_offset
+
VECTOR2I
(
-
l
,
l
)
)
);
c
-
d_offset
+
VECTOR2I
(
-
l
,
l
)
)
);
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
-
d_offset
,
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
-
d_offset
,
c
-
d_offset
-
VECTOR2I
(
l
,
l
)
)
);
c
-
d_offset
-
VECTOR2I
(
l
,
l
)
)
);
}
}
else
else
{
{
// fixme: this could be done more efficiently
// fixme: this could be done more efficiently
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
+
d_offset
,
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
+
d_offset
,
c
+
d_offset
+
VECTOR2I
(
l
,
l
)
)
);
c
+
d_offset
+
VECTOR2I
(
l
,
l
)
)
);
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
-
d_offset
,
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
-
d_offset
,
c
-
d_offset
-
VECTOR2I
(
-
l
,
l
)
)
);
c
-
d_offset
-
VECTOR2I
(
-
l
,
l
)
)
);
...
@@ -640,7 +640,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
...
@@ -640,7 +640,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
for
(
int
diag
=
0
;
diag
<
2
;
diag
++
)
for
(
int
diag
=
0
;
diag
<
2
;
diag
++
)
{
{
SHAPE_LINE_CHAIN
v
;
SHAPE_LINE_CHAIN
v
;
SHAPE_LINE_CHAIN
connect
=
dir
.
BuildInitialTrace
(
l
.
CPoint
(
-
1
),
SHAPE_LINE_CHAIN
connect
=
dir
.
BuildInitialTrace
(
l
.
CPoint
(
-
1
),
line
.
CPoint
(
p
),
diag
==
0
);
line
.
CPoint
(
p
),
diag
==
0
);
DIRECTION_45
dir_bkout
(
l
.
CSegment
(
-
1
)
);
DIRECTION_45
dir_bkout
(
l
.
CSegment
(
-
1
)
);
...
@@ -691,7 +691,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
...
@@ -691,7 +691,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
if
(
!
checkColliding
(
&
tmp
)
)
if
(
!
checkColliding
(
&
tmp
)
)
{
{
/*
if(aEnd)
/*
if(aEnd)
* PNSDisplayDebugLine (l_best, 6);
* PNSDisplayDebugLine (l_best, 6);
* else
* else
* PNSDisplayDebugLine (l_best, 5);*/
* PNSDisplayDebugLine (l_best, 5);*/
...
...
pcbnew/router/pns_router.cpp
View file @
22045b61
...
@@ -53,7 +53,7 @@
...
@@ -53,7 +53,7 @@
using
namespace
std
;
using
namespace
std
;
// an ugly singleton for drawing debug items within the router context.
// an ugly singleton for drawing debug items within the router context.
// To be fixed sometime in the future.
// To be fixed sometime in the future.
static
PNS_ROUTER
*
theRouter
;
static
PNS_ROUTER
*
theRouter
;
...
...
pcbnew/router/pns_shove.cpp
View file @
22045b61
...
@@ -429,7 +429,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( PNS_LINE* aCurrentHead )
...
@@ -429,7 +429,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( PNS_LINE* aCurrentHead )
break
;
break
;
}
}
/*
if(lastWalkSolid == nearest->item)
/*
if(lastWalkSolid == nearest->item)
* {
* {
* fail = true;
* fail = true;
* break;
* break;
...
...
pcbnew/router/pns_shove.h
View file @
22045b61
...
@@ -58,7 +58,7 @@ public:
...
@@ -58,7 +58,7 @@ public:
private
:
private
:
static
const
int
ShoveTimeLimit
=
3000
;
static
const
int
ShoveTimeLimit
=
3000
;
bool
tryShove
(
PNS_NODE
*
aWorld
,
PNS_LINE
*
aTrack
,
PNS_LINE
*
aObstacle
,
bool
tryShove
(
PNS_NODE
*
aWorld
,
PNS_LINE
*
aTrack
,
PNS_LINE
*
aObstacle
,
PNS_SEGMENT
&
aObstacleSeg
,
PNS_LINE
*
aResult
,
bool
aInvertWinding
);
PNS_SEGMENT
&
aObstacleSeg
,
PNS_LINE
*
aResult
,
bool
aInvertWinding
);
ShoveStatus
shoveSingleLine
(
PNS_NODE
*
aNode
,
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
ShoveStatus
shoveSingleLine
(
PNS_NODE
*
aNode
,
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
...
...
pcbnew/router/pns_walkaround.cpp
View file @
22045b61
...
@@ -74,7 +74,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
...
@@ -74,7 +74,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
}
}
}
}
aPath
.
NewWalkaround
(
current_obs
->
hull
,
path_pre
[
0
],
path_walk
[
0
],
aPath
.
NewWalkaround
(
current_obs
->
hull
,
path_pre
[
0
],
path_walk
[
0
],
path_post
[
0
],
aWindingDirection
);
path_post
[
0
],
aWindingDirection
);
aPath
.
NewWalkaround
(
current_obs
->
hull
,
path_pre
[
1
],
path_walk
[
1
],
aPath
.
NewWalkaround
(
current_obs
->
hull
,
path_pre
[
1
],
path_walk
[
1
],
path_post
[
1
],
!
aWindingDirection
);
path_post
[
1
],
!
aWindingDirection
);
...
...
pcbnew/router/pns_walkaround.h
View file @
22045b61
...
@@ -72,7 +72,7 @@ public:
...
@@ -72,7 +72,7 @@ public:
m_cursorApproachMode
=
aEnabled
;
m_cursorApproachMode
=
aEnabled
;
}
}
WalkaroundStatus
Route
(
const
PNS_LINE
&
aInitialPath
,
PNS_LINE
&
aWalkPath
,
WalkaroundStatus
Route
(
const
PNS_LINE
&
aInitialPath
,
PNS_LINE
&
aWalkPath
,
bool
aOptimize
=
true
);
bool
aOptimize
=
true
);
private
:
private
:
...
...
pcbnew/router/router_tool.cpp
View file @
22045b61
...
@@ -100,7 +100,7 @@ int ROUTER_TOOL::getDefaultWidth( int aNetCode )
...
@@ -100,7 +100,7 @@ int ROUTER_TOOL::getDefaultWidth( int aNetCode )
}
}
void
ROUTER_TOOL
::
getNetclassDimensions
(
int
aNetCode
,
int
&
aWidth
,
void
ROUTER_TOOL
::
getNetclassDimensions
(
int
aNetCode
,
int
&
aWidth
,
int
&
aViaDiameter
,
int
&
aViaDrill
)
int
&
aViaDiameter
,
int
&
aViaDrill
)
{
{
BOARD
*
board
=
getModel
<
BOARD
>
(
PCB_T
);
BOARD
*
board
=
getModel
<
BOARD
>
(
PCB_T
);
...
...
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