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
3f320e4d
Commit
3f320e4d
authored
Sep 27, 2013
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Some more comments and code formatting.
parent
6e0c7a93
Changes
21
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
852 additions
and
538 deletions
+852
-538
drawpanel_gal.cpp
common/drawpanel_gal.cpp
+0
-11
seg.cpp
common/geometry/seg.cpp
+63
-61
shape_collisions.cpp
common/geometry/shape_collisions.cpp
+71
-48
shape_index.cpp
common/geometry/shape_index.cpp
+0
-1
shape_line_chain.cpp
common/geometry/shape_line_chain.cpp
+225
-170
action_manager.cpp
common/tool/action_manager.cpp
+4
-3
context_menu.cpp
common/tool/context_menu.cpp
+13
-1
tool_dispatcher.cpp
common/tool/tool_dispatcher.cpp
+26
-12
tool_event.cpp
common/tool/tool_event.cpp
+1
-1
tool_manager.cpp
common/tool/tool_manager.cpp
+3
-7
shape_index.h
include/geometry/shape_index.h
+75
-59
shape_line_chain.h
include/geometry/shape_line_chain.h
+124
-114
action_manager.h
include/tool/action_manager.h
+11
-4
context_menu.h
include/tool/context_menu.h
+53
-5
tool_base.h
include/tool/tool_base.h
+53
-6
tool_dispatcher.h
include/tool/tool_dispatcher.h
+38
-3
tool_event.h
include/tool/tool_event.h
+53
-7
tool_interactive.h
include/tool/tool_interactive.h
+12
-8
move_tool.cpp
pcbnew/tools/move_tool.cpp
+11
-5
selection_area.h
pcbnew/tools/selection_area.h
+1
-0
selection_tool.cpp
pcbnew/tools/selection_tool.cpp
+15
-12
No files found.
common/drawpanel_gal.cpp
View file @
3f320e4d
...
@@ -121,11 +121,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
...
@@ -121,11 +121,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
m_pendingRefresh
=
false
;
m_pendingRefresh
=
false
;
m_lastRefresh
=
wxGetLocalTimeMillis
();
m_lastRefresh
=
wxGetLocalTimeMillis
();
#ifdef __WXDEBUG__
prof_counter
time
;
prof_start
(
&
time
,
false
);
#endif
/* __WXDEBUG__ */
m_gal
->
BeginDrawing
();
m_gal
->
BeginDrawing
();
m_gal
->
SetBackgroundColor
(
KiGfx
::
COLOR4D
(
0.0
,
0.0
,
0.0
,
1.0
)
);
m_gal
->
SetBackgroundColor
(
KiGfx
::
COLOR4D
(
0.0
,
0.0
,
0.0
,
1.0
)
);
m_gal
->
ClearScreen
();
m_gal
->
ClearScreen
();
...
@@ -138,12 +133,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
...
@@ -138,12 +133,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
m_gal
->
DrawCursor
(
m_viewControls
->
GetCursorPosition
()
);
m_gal
->
DrawCursor
(
m_viewControls
->
GetCursorPosition
()
);
m_gal
->
EndDrawing
();
m_gal
->
EndDrawing
();
#ifdef __WXDEBUG__
prof_end
(
&
time
);
wxLogDebug
(
wxT
(
"EDA_DRAW_PANEL_GAL::Refresh: %.0f ms (%.0f fps)"
),
static_cast
<
double
>
(
time
.
value
)
/
1000.0
,
1000000.0
/
static_cast
<
double
>
(
time
.
value
)
);
#endif
/* __WXDEBUG__ */
}
}
...
...
common/geometry/seg.cpp
View file @
3f320e4d
...
@@ -25,126 +25,128 @@
...
@@ -25,126 +25,128 @@
#include <geometry/seg.h>
#include <geometry/seg.h>
template
<
typename
T
>
int
sgn
(
T
val
)
{
template
<
typename
T
>
int
sgn
(
T
val
)
{
return
(
T
(
0
)
<
val
)
-
(
val
<
T
(
0
)
);
return
(
T
(
0
)
<
val
)
-
(
val
<
T
(
0
)
);
}
}
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
);
return
(
nearest
-
aP
).
SquaredEuclideanNorm
()
<=
dist_sq
;
return
(
nearest
-
aP
).
SquaredEuclideanNorm
()
<=
dist_sq
;
}
}
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
)
)
return
0
;
return
0
;
const
VECTOR2I
pts
[
4
]
=
const
VECTOR2I
pts
[
4
]
=
{
{
aSeg
.
NearestPoint
(
a
)
-
a
,
aSeg
.
NearestPoint
(
a
)
-
a
,
aSeg
.
NearestPoint
(
b
)
-
b
,
aSeg
.
NearestPoint
(
b
)
-
b
,
NearestPoint
(
aSeg
.
a
)
-
aSeg
.
a
,
NearestPoint
(
aSeg
.
a
)
-
aSeg
.
a
,
NearestPoint
(
aSeg
.
b
)
-
aSeg
.
b
NearestPoint
(
aSeg
.
b
)
-
aSeg
.
b
};
};
ecoord
m
=
VECTOR2I
::
ECOORD_MAX
;
ecoord
m
=
VECTOR2I
::
ECOORD_MAX
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
for
(
int
i
=
0
;
i
<
4
;
i
++
)
m
=
std
::
min
(
m
,
pts
[
i
].
SquaredEuclideanNorm
());
m
=
std
::
min
(
m
,
pts
[
i
].
SquaredEuclideanNorm
()
);
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
)
&&
ccw
(
a
,
b
,
aSeg
.
a
)
!=
ccw
(
a
,
b
,
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
)
)
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 @
3f320e4d
...
@@ -31,7 +31,8 @@
...
@@ -31,7 +31,8 @@
typedef
VECTOR2I
::
extended_type
ecoord
;
typedef
VECTOR2I
::
extended_type
ecoord
;
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
a
,
const
SHAPE_CIRCLE
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
a
,
const
SHAPE_CIRCLE
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
{
ecoord
min_dist
=
clearance
+
a
.
GetRadius
()
+
b
.
GetRadius
();
ecoord
min_dist
=
clearance
+
a
.
GetRadius
()
+
b
.
GetRadius
();
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
...
@@ -44,12 +45,13 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int cl
...
@@ -44,12 +45,13 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int cl
return
false
;
return
false
;
if
(
needMTV
)
if
(
needMTV
)
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
min_dist_sq
-
dist_sq
))
+
1
);
aMTV
=
delta
.
Resize
(
sqrt
(
abs
(
min_dist_sq
-
dist_sq
)
)
+
1
);
return
true
;
return
true
;
}
}
static
inline
bool
Collide
(
const
SHAPE_RECT
&
a
,
const
SHAPE_CIRCLE
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_RECT
&
a
,
const
SHAPE_CIRCLE
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
{
const
VECTOR2I
c
=
b
.
GetCenter
();
const
VECTOR2I
c
=
b
.
GetCenter
();
const
VECTOR2I
p0
=
a
.
GetPosition
();
const
VECTOR2I
p0
=
a
.
GetPosition
();
...
@@ -58,7 +60,7 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
...
@@ -58,7 +60,7 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
const
ecoord
min_dist
=
clearance
+
r
;
const
ecoord
min_dist
=
clearance
+
r
;
const
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
const
ecoord
min_dist_sq
=
min_dist
*
min_dist
;
if
(
a
.
BBox
(
0
).
Contains
(
c
)
)
if
(
a
.
BBox
(
0
).
Contains
(
c
)
)
return
true
;
return
true
;
const
VECTOR2I
vts
[]
=
{
const
VECTOR2I
vts
[]
=
{
...
@@ -71,73 +73,77 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
...
@@ -71,73 +73,77 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle
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
(
!
needMTV
)
if
(
!
needMTV
)
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
(
!
needMTV
)
if
(
!
needMTV
)
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
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_CIRCLE
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
{
for
(
int
s
=
0
;
s
<
b
.
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
b
.
SegmentCount
();
s
++
)
{
{
if
(
a
.
Collide
(
b
.
CSegment
(
s
),
clearance
)
)
if
(
a
.
Collide
(
b
.
CSegment
(
s
),
clearance
)
)
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
static
inline
bool
Collide
(
const
SHAPE_LINE_CHAIN
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_LINE_CHAIN
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
{
for
(
int
i
=
0
;
i
<
b
.
SegmentCount
()
;
i
++
)
for
(
int
i
=
0
;
i
<
b
.
SegmentCount
()
;
i
++
)
if
(
a
.
Collide
(
b
.
CSegment
(
i
),
clearance
)
)
if
(
a
.
Collide
(
b
.
CSegment
(
i
),
clearance
)
)
return
true
;
return
true
;
return
false
;
return
false
;
}
}
static
inline
bool
Collide
(
const
SHAPE_RECT
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
static
inline
bool
Collide
(
const
SHAPE_RECT
&
a
,
const
SHAPE_LINE_CHAIN
&
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
{
for
(
int
s
=
0
;
s
<
b
.
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
b
.
SegmentCount
();
s
++
)
{
{
SEG
seg
=
b
.
CSegment
(
s
);
SEG
seg
=
b
.
CSegment
(
s
);
if
(
a
.
Collide
(
seg
,
clearance
)
)
if
(
a
.
Collide
(
seg
,
clearance
)
)
return
true
;
return
true
;
}
}
...
@@ -145,66 +151,83 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int
...
@@ -145,66 +151,83 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int
}
}
bool
CollideShapes
(
const
SHAPE
*
a
,
const
SHAPE
*
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
bool
CollideShapes
(
const
SHAPE
*
a
,
const
SHAPE
*
b
,
int
clearance
,
bool
needMTV
,
VECTOR2I
&
aMTV
)
{
{
switch
(
a
->
Type
()
)
switch
(
a
->
Type
()
)
{
{
case
SH_RECT
:
case
SH_RECT
:
switch
(
b
->
Type
()
)
switch
(
b
->
Type
()
)
{
{
case
SH_CIRCLE
:
case
SH_CIRCLE
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
a
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
a
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
case
SH_LINE_CHAIN
:
case
SH_LINE_CHAIN
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
default:
default:
break
;
break
;
}
}
case
SH_CIRCLE
:
case
SH_CIRCLE
:
switch
(
b
->
Type
()
)
switch
(
b
->
Type
()
)
{
{
case
SH_RECT
:
case
SH_RECT
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
b
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
b
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
case
SH_CIRCLE
:
case
SH_CIRCLE
:
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
case
SH_LINE_CHAIN
:
case
SH_LINE_CHAIN
:
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
default:
default:
break
;
break
;
}
}
case
SH_LINE_CHAIN
:
case
SH_LINE_CHAIN
:
switch
(
b
->
Type
()
)
switch
(
b
->
Type
()
)
{
{
case
SH_RECT
:
case
SH_RECT
:
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
b
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_RECT
*>
(
b
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
case
SH_CIRCLE
:
case
SH_CIRCLE
:
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_CIRCLE
*>
(
b
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
clearance
,
needMTV
,
aMTV
);
case
SH_LINE_CHAIN
:
case
SH_LINE_CHAIN
:
return
Collide
(
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
aMTV
);
return
Collide
(
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
a
),
*
static_cast
<
const
SHAPE_LINE_CHAIN
*>
(
b
),
clearance
,
needMTV
,
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_index.cpp
View file @
3f320e4d
...
@@ -30,4 +30,3 @@ const SHAPE* shapeFunctor( SHAPE* aItem )
...
@@ -30,4 +30,3 @@ const SHAPE* shapeFunctor( SHAPE* aItem )
{
{
return
aItem
;
return
aItem
;
}
}
common/geometry/shape_line_chain.cpp
View file @
3f320e4d
...
@@ -28,43 +28,46 @@
...
@@ -28,43 +28,46 @@
using
namespace
std
;
using
namespace
std
;
using
boost
::
optional
;
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
;
...
@@ -74,176 +77,195 @@ const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Reverse() const
...
@@ -74,176 +77,195 @@ const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Reverse() const
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
start_index
,
int
end_index
,
const
VECTOR2I
&
aP
)
void
SHAPE_LINE_CHAIN
::
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
VECTOR2I
&
aP
)
{
{
if
(
end_index
<
0
)
if
(
aEndIndex
<
0
)
end_i
ndex
+=
PointCount
();
aEndI
ndex
+=
PointCount
();
if
(
start_index
<
0
)
if
(
aStartIndex
<
0
)
start_i
ndex
+=
PointCount
();
aStartI
ndex
+=
PointCount
();
if
(
start_index
==
end_index
)
if
(
aStartIndex
==
aEndIndex
)
m_points
[
start_index
]
=
aP
;
m_points
[
aStartIndex
]
=
aP
;
else
{
else
m_points
.
erase
(
m_points
.
begin
()
+
start_index
+
1
,
m_points
.
begin
()
+
end_index
+
1
);
{
m_points
[
start_index
]
=
aP
;
m_points
.
erase
(
m_points
.
begin
()
+
aStartIndex
+
1
,
m_points
.
begin
()
+
aEndIndex
+
1
);
m_points
[
aStartIndex
]
=
aP
;
}
}
}
}
void
SHAPE_LINE_CHAIN
::
Replace
(
int
start_index
,
int
end_index
,
const
SHAPE_LINE_CHAIN
&
aLine
)
void
SHAPE_LINE_CHAIN
::
Replace
(
int
aStartIndex
,
int
aEndIndex
,
const
SHAPE_LINE_CHAIN
&
aLine
)
{
{
if
(
end_index
<
0
)
if
(
aEndIndex
<
0
)
end_i
ndex
+=
PointCount
();
aEndI
ndex
+=
PointCount
();
if
(
start_index
<
0
)
if
(
aStartIndex
<
0
)
start_i
ndex
+=
PointCount
();
aStartI
ndex
+=
PointCount
();
m_points
.
erase
(
m_points
.
begin
()
+
start_index
,
m_points
.
begin
()
+
end_index
+
1
);
m_points
.
erase
(
m_points
.
begin
()
+
aStartIndex
,
m_points
.
begin
()
+
aEndIndex
+
1
);
m_points
.
insert
(
m_points
.
begin
()
+
start_index
,
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
start_index
,
int
end_index
)
void
SHAPE_LINE_CHAIN
::
Remove
(
int
aStartIndex
,
int
aEndIndex
)
{
{
if
(
end_i
ndex
<
0
)
if
(
aEndI
ndex
<
0
)
end_i
ndex
+=
PointCount
();
aEndI
ndex
+=
PointCount
();
if
(
start_i
ndex
<
0
)
if
(
aStartI
ndex
<
0
)
start_i
ndex
+=
PointCount
();
aStartI
ndex
+=
PointCount
();
m_points
.
erase
(
m_points
.
begin
()
+
start_index
,
m_points
.
begin
()
+
end_index
+
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
start_index
,
int
end_index
)
const
const
SHAPE_LINE_CHAIN
SHAPE_LINE_CHAIN
::
Slice
(
int
aStartIndex
,
int
aEndIndex
)
const
{
{
SHAPE_LINE_CHAIN
rv
;
SHAPE_LINE_CHAIN
rv
;
if
(
end_index
<
0
)
if
(
aEndIndex
<
0
)
end_index
+=
PointCount
();
aEndIndex
+=
PointCount
();
if
(
start_index
<
0
)
if
(
aStartIndex
<
0
)
start_index
+=
PointCount
();
aStartIndex
+=
PointCount
();
for
(
int
i
=
aStartIndex
;
i
<=
aEndIndex
;
i
++
)
rv
.
Append
(
m_points
[
i
]
);
for
(
int
i
=
start_index
;
i
<=
end_index
;
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
&
a
,
const
SHAPE_LINE_CHAIN
::
Intersection
&
b
)
bool
operator
()(
const
SHAPE_LINE_CHAIN
::
Intersection
&
aA
,
const
SHAPE_LINE_CHAIN
::
Intersection
&
aB
)
{
{
return
(
m_origin
-
a
.
p
).
EuclideanNorm
()
<
(
m_origin
-
b
.
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
{
}
OPT_VECTOR2I
p
=
a
.
Intersect
(
b
);
else
{
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
);
}
}
}
}
}
}
...
@@ -251,130 +273,152 @@ BOX2I bb_other = aChain.BBox();
...
@@ -251,130 +273,152 @@ BOX2I bb_other = aChain.BBox();
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
)
if
(
s
.
a
==
aP
||
s
.
b
==
aP
)
return
true
;
return
true
;
if
(
s
.
Distance
(
aP
)
<=
1
)
if
(
s
.
Distance
(
aP
)
<=
1
)
return
true
;
return
true
;
}
}
return
false
;
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
{
OPT_VECTOR2I
p
=
CSegment
(
s1
).
Intersect
(
CSegment
(
s2
),
true
);
}
else
{
if
(
p
)
OPT_VECTOR2I
p
=
CSegment
(
s1
).
Intersect
(
CSegment
(
s2
),
true
);
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
>
();
}
}
...
@@ -383,12 +427,15 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
...
@@ -383,12 +427,15 @@ 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
)
{
}
if
(
m_points
[
0
]
==
m_points
[
1
])
else
if
(
PointCount
()
==
2
)
m_points
.
erase
(
m_points
.
end
());
{
if
(
m_points
[
0
]
==
m_points
[
1
]
)
m_points
.
erase
(
m_points
.
end
()
);
return
*
this
;
return
*
this
;
}
}
...
@@ -398,10 +445,11 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
...
@@ -398,10 +445,11 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
// 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
;
}
}
...
@@ -410,56 +458,63 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
...
@@ -410,56 +458,63 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify()
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
++
)
for
(
int
i
=
0
;
i
<
PointCount
();
i
++
)
ss
<<
m_points
[
i
].
x
<<
" "
<<
m_points
[
i
].
y
<<
" "
;
// Format() << " ";
ss
<<
m_points
[
i
].
x
<<
" "
<<
m_points
[
i
].
y
<<
" "
;
// Format() << " ";
return
ss
.
str
();
return
ss
.
str
();
}
}
common/tool/action_manager.cpp
View file @
3f320e4d
...
@@ -52,8 +52,9 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
...
@@ -52,8 +52,9 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
void
ACTION_MANAGER
::
UnregisterAction
(
TOOL_ACTION
*
aAction
)
void
ACTION_MANAGER
::
UnregisterAction
(
TOOL_ACTION
*
aAction
)
{
{
// Indicate that
we
no longer care about the object
// Indicate that
the ACTION_MANAGER
no longer care about the object
aAction
->
setActionMgr
(
NULL
);
aAction
->
setActionMgr
(
NULL
);
aAction
->
setId
(
-
1
);
m_actionNameIndex
.
erase
(
aAction
->
m_name
);
m_actionNameIndex
.
erase
(
aAction
->
m_name
);
m_actionIdIndex
.
erase
(
aAction
->
m_id
);
m_actionIdIndex
.
erase
(
aAction
->
m_id
);
...
@@ -75,7 +76,7 @@ bool ACTION_MANAGER::RunAction( const std::string& aActionName ) const
...
@@ -75,7 +76,7 @@ bool ACTION_MANAGER::RunAction( const std::string& aActionName ) const
std
::
map
<
std
::
string
,
TOOL_ACTION
*>::
const_iterator
it
=
m_actionNameIndex
.
find
(
aActionName
);
std
::
map
<
std
::
string
,
TOOL_ACTION
*>::
const_iterator
it
=
m_actionNameIndex
.
find
(
aActionName
);
if
(
it
==
m_actionNameIndex
.
end
()
)
if
(
it
==
m_actionNameIndex
.
end
()
)
return
false
;
return
false
;
// no action with given name found
runAction
(
it
->
second
);
runAction
(
it
->
second
);
...
@@ -88,7 +89,7 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
...
@@ -88,7 +89,7 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const
std
::
map
<
int
,
TOOL_ACTION
*>::
const_iterator
it
=
m_actionHotKeys
.
find
(
aHotKey
);
std
::
map
<
int
,
TOOL_ACTION
*>::
const_iterator
it
=
m_actionHotKeys
.
find
(
aHotKey
);
if
(
it
==
m_actionHotKeys
.
end
()
)
if
(
it
==
m_actionHotKeys
.
end
()
)
return
false
;
return
false
;
// no appropriate action found for the hotkey
runAction
(
it
->
second
);
runAction
(
it
->
second
);
...
...
common/tool/context_menu.cpp
View file @
3f320e4d
...
@@ -62,13 +62,15 @@ CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) :
...
@@ -62,13 +62,15 @@ CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) :
wxEmptyString
,
wxITEM_NORMAL
)
);
wxEmptyString
,
wxITEM_NORMAL
)
);
}
}
// Copy tool actions that are available to choose from menu
// Copy tool actions that are available to choose from
context
menu
m_toolActions
=
aMenu
.
m_toolActions
;
m_toolActions
=
aMenu
.
m_toolActions
;
}
}
void
CONTEXT_MENU
::
SetTitle
(
const
wxString
&
aTitle
)
void
CONTEXT_MENU
::
SetTitle
(
const
wxString
&
aTitle
)
{
{
// 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
)
{
{
...
@@ -85,12 +87,18 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
...
@@ -85,12 +87,18 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
void
CONTEXT_MENU
::
Add
(
const
wxString
&
aLabel
,
int
aId
)
void
CONTEXT_MENU
::
Add
(
const
wxString
&
aLabel
,
int
aId
)
{
{
#ifdef DEBUG
if
(
m_menu
.
FindItem
(
aId
)
!=
NULL
)
wxLogWarning
(
wxT
(
"Adding more than one menu entry with the same ID may result in"
"undefined behaviour"
)
);
#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
)
);
}
}
void
CONTEXT_MENU
::
Add
(
const
TOOL_ACTION
&
aAction
)
void
CONTEXT_MENU
::
Add
(
const
TOOL_ACTION
&
aAction
)
{
{
/// ID numbers for tool actions need to have a value higher than m_actionId
int
id
=
m_actionId
+
aAction
.
GetId
();
int
id
=
m_actionId
+
aAction
.
GetId
();
wxString
menuEntry
;
wxString
menuEntry
;
...
@@ -110,6 +118,7 @@ void CONTEXT_MENU::Clear()
...
@@ -110,6 +118,7 @@ void CONTEXT_MENU::Clear()
{
{
m_titleSet
=
false
;
m_titleSet
=
false
;
// 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
)
);
...
@@ -144,15 +153,18 @@ void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent )
...
@@ -144,15 +153,18 @@ void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent )
if
(
type
==
wxEVT_MENU_HIGHLIGHT
)
if
(
type
==
wxEVT_MENU_HIGHLIGHT
)
evt
=
TOOL_EVENT
(
TC_Command
,
TA_ContextMenuUpdate
,
aEvent
.
GetId
()
);
evt
=
TOOL_EVENT
(
TC_Command
,
TA_ContextMenuUpdate
,
aEvent
.
GetId
()
);
else
if
(
type
==
wxEVT_COMMAND_MENU_SELECTED
)
else
if
(
type
==
wxEVT_COMMAND_MENU_SELECTED
)
{
{
if
(
aEvent
.
GetId
()
>
m_actionId
)
if
(
aEvent
.
GetId
()
>
m_actionId
)
{
{
// Handling TOOL_ACTIONs
if
(
m_menu
->
m_toolActions
.
count
(
aEvent
.
GetId
()
)
==
1
)
if
(
m_menu
->
m_toolActions
.
count
(
aEvent
.
GetId
()
)
==
1
)
evt
=
m_menu
->
m_toolActions
[
aEvent
.
GetId
()]
->
GetEvent
();
evt
=
m_menu
->
m_toolActions
[
aEvent
.
GetId
()]
->
GetEvent
();
}
}
else
else
{
{
// Handling common menu entries
evt
=
TOOL_EVENT
(
TC_Command
,
TA_ContextMenuChoice
,
aEvent
.
GetId
()
);
evt
=
TOOL_EVENT
(
TC_Command
,
TA_ContextMenuChoice
,
aEvent
.
GetId
()
);
}
}
}
}
...
...
common/tool/tool_dispatcher.cpp
View file @
3f320e4d
...
@@ -42,28 +42,41 @@ using boost::optional;
...
@@ -42,28 +42,41 @@ using boost::optional;
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
,
bool
aTriggerMenu
=
false
)
:
const
wxEventType
&
aUpEvent
)
:
button
(
aButton
),
button
(
aButton
),
downEvent
(
aDownEvent
),
downEvent
(
aDownEvent
),
upEvent
(
aUpEvent
),
upEvent
(
aUpEvent
)
triggerContextMenu
(
aTriggerMenu
)
{};
{};
///> Flag indicating that dragging is active for the given button.
bool
dragging
;
bool
dragging
;
///> Flag indicating that the given button is pressed.
bool
pressed
;
bool
pressed
;
///> Point where dragging has started (in world coordinates).
VECTOR2D
dragOrigin
;
VECTOR2D
dragOrigin
;
///> Point where click event has occurred.
VECTOR2D
downPosition
;
VECTOR2D
downPosition
;
///> Difference between drag origin point and current mouse position (expressed as distance in
///> pixels).
double
dragMaxDelta
;
double
dragMaxDelta
;
///> Determines the mouse button for which information are stored.
TOOL_MouseButtons
button
;
TOOL_MouseButtons
button
;
///> The type of wxEvent that determines mouse button press.
wxEventType
downEvent
;
wxEventType
downEvent
;
///> The type of wxEvent that determines mouse button release.
wxEventType
upEvent
;
wxEventType
upEvent
;
bool
triggerContextMenu
;
///> Time stamp for the last mouse button press event.
wxLongLong
downTimestamp
;
wxLongLong
downTimestamp
;
///> Restores initial state.
void
Reset
()
void
Reset
()
{
{
dragging
=
false
;
dragging
=
false
;
...
@@ -76,7 +89,7 @@ TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditF
...
@@ -76,7 +89,7 @@ TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditF
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
,
true
)
);
m_buttons
.
push_back
(
new
ButtonState
(
MB_Right
,
wxEVT_RIGHT_DOWN
,
wxEVT_RIGHT_UP
)
);
m_buttons
.
push_back
(
new
ButtonState
(
MB_Middle
,
wxEVT_MIDDLE_DOWN
,
wxEVT_MIDDLE_UP
)
);
m_buttons
.
push_back
(
new
ButtonState
(
MB_Middle
,
wxEVT_MIDDLE_DOWN
,
wxEVT_MIDDLE_UP
)
);
ResetState
();
ResetState
();
...
@@ -131,7 +144,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
...
@@ -131,7 +144,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
int
mods
=
decodeModifiers
(
static_cast
<
wxMouseEvent
*>
(
&
aEvent
)
);
int
mods
=
decodeModifiers
(
static_cast
<
wxMouseEvent
*>
(
&
aEvent
)
);
int
args
=
st
->
button
|
mods
;
int
args
=
st
->
button
|
mods
;
if
(
down
)
if
(
down
)
// Handle mouse button press
{
{
st
->
downTimestamp
=
wxGetLocalTimeMillis
();
st
->
downTimestamp
=
wxGetLocalTimeMillis
();
st
->
dragOrigin
=
m_lastMousePos
;
st
->
dragOrigin
=
m_lastMousePos
;
...
@@ -140,7 +153,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
...
@@ -140,7 +153,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
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
)
else
if
(
up
)
// Handle mouse button release
{
{
st
->
pressed
=
false
;
st
->
pressed
=
false
;
...
@@ -148,6 +161,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
...
@@ -148,6 +161,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
{
{
wxLongLong
t
=
wxGetLocalTimeMillis
();
wxLongLong
t
=
wxGetLocalTimeMillis
();
// 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
;
...
@@ -157,7 +171,6 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
...
@@ -157,7 +171,6 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
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
);
...
@@ -208,6 +221,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
...
@@ -208,6 +221,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
{
{
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
;
...
@@ -251,7 +265,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
...
@@ -251,7 +265,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
}
}
void
TOOL_DISPATCHER
::
DispatchWxCommand
(
wxCommandEvent
&
aEvent
)
void
TOOL_DISPATCHER
::
DispatchWxCommand
(
const
wxCommandEvent
&
aEvent
)
{
{
bool
activateTool
=
false
;
bool
activateTool
=
false
;
std
::
string
toolName
;
std
::
string
toolName
;
...
...
common/tool/tool_event.cpp
View file @
3f320e4d
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
#include <cstring>
#include <cstring>
#include <string>
#include <string>
#include <base_struct.h>
//
#include <base_struct.h>
#include <tool/tool_event.h>
#include <tool/tool_event.h>
#include <tool/tool_manager.h>
#include <tool/tool_manager.h>
...
...
common/tool/tool_manager.cpp
View file @
3f320e4d
...
@@ -288,10 +288,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
...
@@ -288,10 +288,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& 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
// The couroutine has finished
finishTool
(
st
);
}
// 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
...
@@ -303,6 +300,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
...
@@ -303,6 +300,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
BOOST_FOREACH
(
TOOL_STATE
*
st
,
m_toolState
|
boost
::
adaptors
::
map_values
)
BOOST_FOREACH
(
TOOL_STATE
*
st
,
m_toolState
|
boost
::
adaptors
::
map_values
)
{
{
// the tool state handler is waiting for events (i.e. called Wait() method)
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
...
@@ -324,9 +322,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
...
@@ -324,9 +322,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent )
st
->
cofunc
->
Call
(
aEvent
);
st
->
cofunc
->
Call
(
aEvent
);
if
(
!
st
->
cofunc
->
Running
()
)
if
(
!
st
->
cofunc
->
Running
()
)
{
finishTool
(
st
);
// The couroutine has finished
finishTool
(
st
);
}
}
}
}
}
}
}
...
...
include/geometry/shape_index.h
View file @
3f320e4d
...
@@ -93,28 +93,27 @@ void acceptVisitor( T object, V visitor )
...
@@ -93,28 +93,27 @@ void acceptVisitor( T object, V visitor )
* @param minDistance minimum collision distance
* @param minDistance minimum collision distance
* @return if object and anotherObject collide
* @return if object and anotherObject collide
*/
*/
template
<
class
T
,
class
U
>
template
<
class
T
,
class
U
>
bool
collide
(
T
object
,
U
anotherObject
,
int
minDistance
)
bool
collide
(
T
object
,
U
anotherObject
,
int
minDistance
)
{
{
return
shapeFunctor
(
object
)
->
Collide
(
anotherObject
,
minDistance
);
return
shapeFunctor
(
object
)
->
Collide
(
anotherObject
,
minDistance
);
}
}
template
<
class
T
,
class
V
>
template
<
class
T
,
class
V
>
bool
queryCallback
(
T
shape
,
void
*
context
)
{
bool
queryCallback
(
T
shape
,
void
*
context
)
{
V
*
visitor
=
(
V
*
)
context
;
V
*
visitor
=
(
V
*
)
context
;
acceptVisitor
<
T
,
V
>
(
shape
,
*
visitor
);
acceptVisitor
<
T
,
V
>
(
shape
,
*
visitor
);
return
true
;
return
true
;
}
}
template
<
class
T
=
SHAPE
*>
template
<
class
T
=
SHAPE
*>
class
SHAPE_INDEX
{
class
SHAPE_INDEX
{
public
:
public
:
class
Iterator
class
Iterator
{
{
private
:
private
:
typedef
typename
RTree
<
T
,
int
,
2
,
float
>::
Iterator
RTreeIterator
;
typedef
typename
RTree
<
T
,
int
,
2
,
float
>::
Iterator
RTreeIterator
;
RTreeIterator
iterator
;
RTreeIterator
iterator
;
...
@@ -124,20 +123,21 @@ class SHAPE_INDEX {
...
@@ -124,20 +123,21 @@ class SHAPE_INDEX {
* Setup the internal tree iterator.
* Setup the internal tree iterator.
* @param tree pointer to a RTREE object
* @param tree pointer to a RTREE object
*/
*/
void
Init
(
RTree
<
T
,
int
,
2
,
float
>*
tree
)
{
void
Init
(
RTree
<
T
,
int
,
2
,
float
>*
tree
)
tree
->
GetFirst
(
iterator
);
{
tree
->
GetFirst
(
iterator
);
}
}
public
:
public
:
/**
/**
* Iterator constructor
* Iterator constructor
*
*
* Creates an iterator for the index object
* Creates an iterator for the index object
* @param index SHAPE_INDEX object to iterate
* @param index SHAPE_INDEX object to iterate
*/
*/
Iterator
(
SHAPE_INDEX
*
index
)
{
Iterator
(
SHAPE_INDEX
*
index
)
Init
(
index
->
m_tree
);
{
Init
(
index
->
m_tree
);
}
}
/**
/**
...
@@ -145,7 +145,8 @@ class SHAPE_INDEX {
...
@@ -145,7 +145,8 @@ class SHAPE_INDEX {
*
*
* Returns the next data element.
* Returns the next data element.
*/
*/
T
operator
*
()
{
T
operator
*
()
{
return
*
iterator
;
return
*
iterator
;
}
}
...
@@ -154,7 +155,8 @@ class SHAPE_INDEX {
...
@@ -154,7 +155,8 @@ class SHAPE_INDEX {
*
*
* Shifts the iterator to the next element.
* Shifts the iterator to the next element.
*/
*/
bool
operator
++
()
{
bool
operator
++
()
{
return
++
iterator
;
return
++
iterator
;
}
}
...
@@ -163,7 +165,8 @@ class SHAPE_INDEX {
...
@@ -163,7 +165,8 @@ class SHAPE_INDEX {
*
*
* Shifts the iterator to the next element.
* Shifts the iterator to the next element.
*/
*/
bool
operator
++
(
int
)
{
bool
operator
++
(
int
)
{
return
++
iterator
;
return
++
iterator
;
}
}
...
@@ -173,7 +176,8 @@ class SHAPE_INDEX {
...
@@ -173,7 +176,8 @@ class SHAPE_INDEX {
* Checks if the iterator has reached the end.
* Checks if the iterator has reached the end.
* @return true if it is in an invalid position (data finished)
* @return true if it is in an invalid position (data finished)
*/
*/
bool
IsNull
()
{
bool
IsNull
()
{
return
iterator
.
IsNull
();
return
iterator
.
IsNull
();
}
}
...
@@ -183,7 +187,8 @@ class SHAPE_INDEX {
...
@@ -183,7 +187,8 @@ class SHAPE_INDEX {
* Checks if the iterator has not reached the end.
* Checks if the iterator has not reached the end.
* @return true if it is in an valid position (data not finished)
* @return true if it is in an valid position (data not finished)
*/
*/
bool
IsNotNull
()
{
bool
IsNotNull
()
{
return
iterator
.
IsNotNull
();
return
iterator
.
IsNotNull
();
}
}
...
@@ -192,12 +197,13 @@ class SHAPE_INDEX {
...
@@ -192,12 +197,13 @@ class SHAPE_INDEX {
*
*
* Returns the current element of the iterator and moves to the next
* Returns the current element of the iterator and moves to the next
* position.
* position.
* @return SHAPE object pointed by the iterator before moving to the
* @return SHAPE object pointed by the iterator before moving to the next position.
* next position.
*/
*/
T
Next
()
{
T
Next
()
{
T
object
=
*
iterator
;
T
object
=
*
iterator
;
++
iterator
;
++
iterator
;
return
object
;
return
object
;
}
}
};
};
...
@@ -210,17 +216,17 @@ class SHAPE_INDEX {
...
@@ -210,17 +216,17 @@ class SHAPE_INDEX {
* Function Add()
* Function Add()
*
*
* Adds a SHAPE to the index.
* Adds a SHAPE to the index.
* @param
shape the new SHAPE
* @param
aShape is the new SHAPE.
*/
*/
void
Add
(
T
s
hape
);
void
Add
(
T
aS
hape
);
/**
/**
* Function Remove()
* Function Remove()
*
*
* Removes a SHAPE to the index.
* Removes a SHAPE to the index.
* @param
shape the new SHAPE
* @param
aShape is the new SHAPE.
*/
*/
void
Remove
(
T
s
hape
);
void
Remove
(
T
aS
hape
);
/**
/**
* Function RemoveAll()
* Function RemoveAll()
...
@@ -236,12 +242,14 @@ class SHAPE_INDEX {
...
@@ -236,12 +242,14 @@ class SHAPE_INDEX {
* @param visitor Visitor object to be run
* @param visitor Visitor object to be run
*/
*/
template
<
class
V
>
template
<
class
V
>
void
Accept
(
V
v
isitor
)
void
Accept
(
V
aV
isitor
)
{
{
Iterator
iter
=
this
->
Begin
();
Iterator
iter
=
this
->
Begin
();
while
(
!
iter
.
IsNull
())
{
while
(
!
iter
.
IsNull
()
)
{
T
shape
=
*
iter
;
T
shape
=
*
iter
;
acceptVisitor
(
shape
,
visitor
);
acceptVisitor
(
shape
,
aVisitor
);
iter
++
;
iter
++
;
}
}
}
}
...
@@ -262,17 +270,16 @@ class SHAPE_INDEX {
...
@@ -262,17 +270,16 @@ class SHAPE_INDEX {
* @param minDistance distance threshold
* @param minDistance distance threshold
* @param visitor object to be invoked on every object contained in the search area.
* @param visitor object to be invoked on every object contained in the search area.
*/
*/
template
<
class
V
>
template
<
class
V
>
int
Query
(
const
SHAPE
*
shape
,
int
minDistance
,
V
&
v
isitor
,
bool
aExact
)
int
Query
(
const
SHAPE
*
aShape
,
int
aMinDistance
,
V
&
aV
isitor
,
bool
aExact
)
{
{
BOX2I
box
=
s
hape
->
BBox
();
BOX2I
box
=
aS
hape
->
BBox
();
box
.
Inflate
(
minDistance
);
box
.
Inflate
(
aMinDistance
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
return
this
->
m_tree
->
Search
(
min
,
max
,
visitor
);
return
this
->
m_tree
->
Search
(
min
,
max
,
aVisitor
);
}
}
/**
/**
...
@@ -284,7 +291,6 @@ class SHAPE_INDEX {
...
@@ -284,7 +291,6 @@ class SHAPE_INDEX {
Iterator
Begin
();
Iterator
Begin
();
private
:
private
:
RTree
<
T
,
int
,
2
,
float
>*
m_tree
;
RTree
<
T
,
int
,
2
,
float
>*
m_tree
;
};
};
...
@@ -293,58 +299,68 @@ class SHAPE_INDEX {
...
@@ -293,58 +299,68 @@ class SHAPE_INDEX {
*/
*/
template
<
class
T
>
template
<
class
T
>
SHAPE_INDEX
<
T
>::
SHAPE_INDEX
()
{
SHAPE_INDEX
<
T
>::
SHAPE_INDEX
()
{
this
->
m_tree
=
new
RTree
<
T
,
int
,
2
,
float
>
();
this
->
m_tree
=
new
RTree
<
T
,
int
,
2
,
float
>
();
}
}
template
<
class
T
>
template
<
class
T
>
SHAPE_INDEX
<
T
>::~
SHAPE_INDEX
()
{
SHAPE_INDEX
<
T
>::~
SHAPE_INDEX
()
{
delete
this
->
m_tree
;
delete
this
->
m_tree
;
}
}
template
<
class
T
>
template
<
class
T
>
void
SHAPE_INDEX
<
T
>::
Add
(
T
shape
)
{
void
SHAPE_INDEX
<
T
>::
Add
(
T
aShape
)
BOX2I
box
=
boundingBox
(
shape
);
{
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()};
BOX2I
box
=
boundingBox
(
aShape
);
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()};
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
this
->
m_tree
->
Insert
(
min
,
max
,
shape
);
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
this
->
m_tree
->
Insert
(
min
,
max
,
aShape
);
}
}
template
<
class
T
>
template
<
class
T
>
void
SHAPE_INDEX
<
T
>::
Remove
(
T
shape
)
{
void
SHAPE_INDEX
<
T
>::
Remove
(
T
aShape
)
BOX2I
box
=
boundingBox
(
shape
);
{
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()};
BOX2I
box
=
boundingBox
(
aShape
);
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()};
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
this
->
m_tree
->
Remove
(
min
,
max
,
shape
);
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
this
->
m_tree
->
Remove
(
min
,
max
,
aShape
);
}
}
template
<
class
T
>
template
<
class
T
>
void
SHAPE_INDEX
<
T
>::
RemoveAll
()
{
void
SHAPE_INDEX
<
T
>::
RemoveAll
()
{
this
->
m_tree
->
RemoveAll
();
this
->
m_tree
->
RemoveAll
();
}
}
template
<
class
T
>
template
<
class
T
>
void
SHAPE_INDEX
<
T
>::
Reindex
()
{
void
SHAPE_INDEX
<
T
>::
Reindex
()
{
RTree
<
T
,
int
,
2
,
float
>*
newTree
;
RTree
<
T
,
int
,
2
,
float
>*
newTree
;
newTree
=
new
RTree
<
T
,
int
,
2
,
float
>
();
newTree
=
new
RTree
<
T
,
int
,
2
,
float
>
();
Iterator
iter
=
this
->
Begin
();
Iterator
iter
=
this
->
Begin
();
while
(
!
iter
.
IsNull
())
{
while
(
!
iter
.
IsNull
()
)
{
T
shape
=
*
iter
;
T
shape
=
*
iter
;
BOX2I
box
=
boundingBox
(
shape
);
BOX2I
box
=
boundingBox
(
shape
);
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
min
[
2
]
=
{
box
.
GetX
(),
box
.
GetY
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
int
max
[
2
]
=
{
box
.
GetRight
(),
box
.
GetBottom
()
};
newTree
->
Insert
(
min
,
max
,
shape
);
newTree
->
Insert
(
min
,
max
,
shape
);
iter
++
;
iter
++
;
}
}
delete
this
->
m_tree
;
delete
this
->
m_tree
;
this
->
m_tree
=
newTree
;
this
->
m_tree
=
newTree
;
}
}
template
<
class
T
>
template
<
class
T
>
typename
SHAPE_INDEX
<
T
>::
Iterator
SHAPE_INDEX
<
T
>::
Begin
()
{
typename
SHAPE_INDEX
<
T
>::
Iterator
SHAPE_INDEX
<
T
>::
Begin
()
return
Iterator
(
this
);
{
return
Iterator
(
this
);
}
}
#endif
#endif
include/geometry/shape_line_chain.h
View file @
3f320e4d
...
@@ -43,7 +43,6 @@
...
@@ -43,7 +43,6 @@
* 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
;
...
@@ -55,7 +54,8 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -55,7 +54,8 @@ class SHAPE_LINE_CHAIN : public SHAPE {
*
*
* 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()
...
@@ -71,45 +71,45 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -71,45 +71,45 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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
&
a
,
const
VECTOR2I
&
b
)
:
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
]
=
a
;
m_points
[
0
]
=
a
A
;
m_points
[
1
]
=
b
;
m_points
[
1
]
=
aB
;
}
}
SHAPE_LINE_CHAIN
(
const
VECTOR2I
&
a
,
const
VECTOR2I
&
b
,
const
VECTOR2I
&
c
)
:
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
]
=
a
;
m_points
[
0
]
=
a
A
;
m_points
[
1
]
=
b
;
m_points
[
1
]
=
aB
;
m_points
[
2
]
=
c
;
m_points
[
2
]
=
aC
;
}
}
SHAPE_LINE_CHAIN
(
const
VECTOR2I
*
aV
,
int
aCount
)
:
SHAPE_LINE_CHAIN
(
const
VECTOR2I
*
v
,
int
count
)
:
SHAPE
(
SH_LINE_CHAIN
),
SHAPE
(
SH_LINE_CHAIN
),
m_closed
(
false
)
m_closed
(
false
)
{
{
m_points
.
resize
(
count
);
m_points
.
resize
(
aCount
);
for
(
int
i
=
0
;
i
<
count
;
i
++
)
m_points
[
i
]
=
*
v
++
;
for
(
int
i
=
0
;
i
<
aCount
;
i
++
)
m_points
[
i
]
=
*
aV
++
;
}
}
~
SHAPE_LINE_CHAIN
()
{};
~
SHAPE_LINE_CHAIN
()
{};
...
@@ -118,7 +118,8 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -118,7 +118,8 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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
;
}
}
...
@@ -129,7 +130,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -129,7 +130,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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
;
}
}
...
@@ -153,9 +154,10 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -153,9 +154,10 @@ class SHAPE_LINE_CHAIN : public SHAPE {
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
);
}
}
/**
/**
...
@@ -167,86 +169,88 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -167,86 +169,88 @@ class SHAPE_LINE_CHAIN : public SHAPE {
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
i
ndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* @param
aI
ndex: 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
index
)
SEG
Segment
(
int
aIndex
)
{
{
if
(
index
<
0
)
if
(
aIndex
<
0
)
i
ndex
+=
SegmentCount
();
aI
ndex
+=
SegmentCount
();
if
(
index
==
(
m_points
.
size
()
-
1
)
&&
m_closed
)
if
(
aIndex
==
(
m_points
.
size
()
-
1
)
&&
m_closed
)
return
SEG
(
m_points
[
index
],
m_points
[
0
],
i
ndex
);
return
SEG
(
m_points
[
aIndex
],
m_points
[
0
],
aI
ndex
);
else
else
return
SEG
(
m_points
[
index
],
m_points
[
index
+
1
],
i
ndex
);
return
SEG
(
m_points
[
aIndex
],
m_points
[
aIndex
+
1
],
aI
ndex
);
}
}
/**
/**
* 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
i
ndex: index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means
* @param
aI
ndex: 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
i
ndex
)
const
const
SEG
CSegment
(
int
aI
ndex
)
const
{
{
if
(
index
<
0
)
if
(
aIndex
<
0
)
i
ndex
+=
SegmentCount
();
aI
ndex
+=
SegmentCount
();
if
(
index
==
(
m_points
.
size
()
-
1
)
&&
m_closed
)
if
(
aIndex
==
(
m_points
.
size
()
-
1
)
&&
m_closed
)
return
SEG
(
const_cast
<
VECTOR2I
&>
(
m_points
[
index
]),
return
SEG
(
const_cast
<
VECTOR2I
&>
(
m_points
[
aIndex
]
),
const_cast
<
VECTOR2I
&>
(
m_points
[
0
]),
i
ndex
);
const_cast
<
VECTOR2I
&>
(
m_points
[
0
]
),
aI
ndex
);
else
else
return
SEG
(
const_cast
<
VECTOR2I
&>
(
m_points
[
index
]),
return
SEG
(
const_cast
<
VECTOR2I
&>
(
m_points
[
aIndex
]
),
const_cast
<
VECTOR2I
&>
(
m_points
[
index
+
1
]),
i
ndex
);
const_cast
<
VECTOR2I
&>
(
m_points
[
aIndex
+
1
]
),
aI
ndex
);
}
}
/**
/**
* 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
i
ndex index of the point
* @param
aI
ndex index of the point
* @return reference to the point
* @return reference to the point
*/
*/
VECTOR2I
&
Point
(
int
index
)
VECTOR2I
&
Point
(
int
aIndex
)
{
{
if
(
index
<
0
)
if
(
aIndex
<
0
)
index
+=
PointCount
();
aIndex
+=
PointCount
();
return
m_points
[
index
];
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
i
ndex index of the point
* @param
aI
ndex index of the point
* @return const reference to the point
* @return const reference to the point
*/
*/
const
VECTOR2I
&
CPoint
(
int
i
ndex
)
const
const
VECTOR2I
&
CPoint
(
int
aI
ndex
)
const
{
{
if
(
index
<
0
)
if
(
aIndex
<
0
)
index
+=
PointCount
();
aIndex
+=
PointCount
();
return
m_points
[
index
];
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()
*
*
...
@@ -255,7 +259,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -255,7 +259,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* @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()
...
@@ -265,7 +269,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -265,7 +269,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* @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()
...
@@ -275,8 +279,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -275,8 +279,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* @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()
...
@@ -285,7 +288,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -285,7 +288,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* @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()
...
@@ -307,13 +310,13 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -307,13 +310,13 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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
x
X coordinate of the new point
* @param
aX is
X coordinate of the new point
* @param
y
Y coordinate of the new point
* @param
aY is
Y coordinate of the new point
*/
*/
void
Append
(
int
x
,
int
y
)
void
Append
(
int
aX
,
int
aY
)
{
{
VECTOR2I
v
(
x
,
y
);
VECTOR2I
v
(
aX
,
aY
);
Append
(
v
);
Append
(
v
);
}
}
/**
/**
...
@@ -322,15 +325,15 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -322,15 +325,15 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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
);
}
}
}
}
...
@@ -340,22 +343,23 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -340,22 +343,23 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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
);
}
}
}
}
...
@@ -364,30 +368,31 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -364,30 +368,31 @@ class SHAPE_LINE_CHAIN : public SHAPE {
*
*
* 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
start_i
ndex start of the point range to be replaced (inclusive)
* @param
aStartI
ndex start of the point range to be replaced (inclusive)
* @param
end_i
ndex end of the point range to be replaced (inclusive)
* @param
aEndI
ndex end of the point range to be replaced (inclusive)
* @param aP replacement point
* @param aP replacement point
*/
*/
void
Replace
(
int
start_index
,
int
end_index
,
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 line chain aLine.
* Replaces points with indices in range [start_index, end_index] with the points from
* @param start_index start of the point range to be replaced (inclusive)
* line chain aLine.
* @param end_index end 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 aLine replacement line chain.
* @param aLine replacement line chain.
*/
*/
void
Replace
(
int
start_index
,
int
end_index
,
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
start_i
ndex start of the point range to be replaced (inclusive)
* @param
aStartI
ndex start of the point range to be replaced (inclusive)
* @param
end_i
ndex end of the point range to be replaced (inclusive)
* @param
aEndI
ndex end of the point range to be replaced (inclusive)
*/
*/
void
Remove
(
int
start_index
,
int
end_index
);
void
Remove
(
int
aStartIndex
,
int
aEndIndex
);
/**
/**
* Function Split()
* Function Split()
...
@@ -397,7 +402,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -397,7 +402,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* @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()
...
@@ -412,26 +417,25 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -412,26 +417,25 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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
start_i
ndex start of the point range to be returned (inclusive)
* @param
aStartI
ndex start of the point range to be returned (inclusive)
* @param
end_i
ndex end of the point range to be returned (inclusive)
* @param
aEndI
ndex end of the point range to be returned (inclusive)
* @return cut line chain.
* @return cut line chain.
*/
*/
const
SHAPE_LINE_CHAIN
Slice
(
int
start_index
,
int
end_index
=
-
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
&
a
,
const
Intersection
&
b
)
bool
operator
()(
const
Intersection
&
aA
,
const
Intersection
&
aB
)
{
{
return
(
m_origin
-
a
.
p
).
EuclideanNorm
()
<
(
m_origin
-
b
.
p
).
EuclideanNorm
();
return
(
m_origin
-
aA
.
p
).
EuclideanNorm
()
<
(
m_origin
-
aB
.
p
).
EuclideanNorm
();
}
}
VECTOR2I
m_origin
;
VECTOR2I
m_origin
;
};
};
/**
/**
* Function Intersect()
* Function Intersect()
*
*
...
@@ -452,7 +456,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -452,7 +456,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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()
...
@@ -461,7 +465,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -461,7 +465,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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()
...
@@ -471,7 +475,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -471,7 +475,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* @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()
...
@@ -480,7 +484,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -480,7 +484,7 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* @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()
...
@@ -504,26 +508,32 @@ class SHAPE_LINE_CHAIN : public SHAPE {
...
@@ -504,26 +508,32 @@ class SHAPE_LINE_CHAIN : public SHAPE {
* 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
&
rhs
)
const
bool
operator
!=
(
const
SHAPE_LINE_CHAIN
&
aRhs
)
const
{
{
if
(
PointCount
()
!=
rhs
.
PointCount
()
)
if
(
PointCount
()
!=
aRhs
.
PointCount
()
)
return
true
;
return
true
;
for
(
int
i
=
0
;
i
<
PointCount
();
i
++
)
if
(
CPoint
(
i
)
!=
rhs
.
CPoint
(
i
)
)
for
(
int
i
=
0
;
i
<
PointCount
();
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
;
};
};
...
...
include/tool/action_manager.h
View file @
3f320e4d
...
@@ -43,21 +43,21 @@ public:
...
@@ -43,21 +43,21 @@ public:
/**
/**
* Function RegisterAction()
* Function RegisterAction()
* Adds a tool action to the manager
set
and sets it up. After that is is possible to invoke
* Adds a tool action to the manager and sets it up. After that is is possible to invoke
* the action using hotkeys or its name.
* the action using hotkeys or
sending a command event with
its name.
* @param aAction: action to be added. Ownership is not transferred.
* @param aAction: action to be added. Ownership is not transferred.
*/
*/
void
RegisterAction
(
TOOL_ACTION
*
aAction
);
void
RegisterAction
(
TOOL_ACTION
*
aAction
);
/**
/**
* Function UnregisterAction()
* Function UnregisterAction()
* Removes a tool action from the manager
set
and makes it unavailable for further usage.
* Removes a tool action from the manager and makes it unavailable for further usage.
* @param aAction: action to be removed.
* @param aAction: action to be removed.
*/
*/
void
UnregisterAction
(
TOOL_ACTION
*
aAction
);
void
UnregisterAction
(
TOOL_ACTION
*
aAction
);
/**
/**
* Generates an unique ID from for a
tool
with given name.
* Generates an unique ID from for a
n action
with given name.
*/
*/
static
int
MakeActionId
(
const
std
::
string
&
aActionName
);
static
int
MakeActionId
(
const
std
::
string
&
aActionName
);
...
@@ -82,9 +82,16 @@ public:
...
@@ -82,9 +82,16 @@ public:
bool
RunHotKey
(
int
aHotKey
)
const
;
bool
RunHotKey
(
int
aHotKey
)
const
;
private
:
private
:
///> Tool manager needed to run actions
TOOL_MANAGER
*
m_toolMgr
;
TOOL_MANAGER
*
m_toolMgr
;
///> Map for indexing actions by their IDs
std
::
map
<
int
,
TOOL_ACTION
*>
m_actionIdIndex
;
std
::
map
<
int
,
TOOL_ACTION
*>
m_actionIdIndex
;
///> Map for indexing actions by their names
std
::
map
<
std
::
string
,
TOOL_ACTION
*>
m_actionNameIndex
;
std
::
map
<
std
::
string
,
TOOL_ACTION
*>
m_actionNameIndex
;
///> Map for indexing actions by their hotkeys
std
::
map
<
int
,
TOOL_ACTION
*>
m_actionHotKeys
;
std
::
map
<
int
,
TOOL_ACTION
*>
m_actionHotKeys
;
/**
/**
...
...
include/tool/context_menu.h
View file @
3f320e4d
...
@@ -29,7 +29,6 @@
...
@@ -29,7 +29,6 @@
#include <tool/tool_action.h>
#include <tool/tool_action.h>
#include <map>
#include <map>
class
wxMenu
;
class
TOOL_INTERACTIVE
;
class
TOOL_INTERACTIVE
;
/**
/**
...
@@ -40,53 +39,102 @@ class TOOL_INTERACTIVE;
...
@@ -40,53 +39,102 @@ class TOOL_INTERACTIVE;
*/
*/
class
CONTEXT_MENU
class
CONTEXT_MENU
{
{
public
:
public
:
///> Default constructor
CONTEXT_MENU
();
CONTEXT_MENU
();
///> Copy constructor
CONTEXT_MENU
(
const
CONTEXT_MENU
&
aMenu
);
CONTEXT_MENU
(
const
CONTEXT_MENU
&
aMenu
);
/**
* Function SetTitle()
* Sets title for the context menu. The title is shown as a text label shown on the top of
* the menu.
* @param aTitle is the new title.
*/
void
SetTitle
(
const
wxString
&
aTitle
);
void
SetTitle
(
const
wxString
&
aTitle
);
/**
* Function Add()
* Adds an entry to the menu. After highlighting/selecting the entry, a TOOL_EVENT command is
* sent that contains ID of the entry.
* @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.
*/
void
Add
(
const
wxString
&
aLabel
,
int
aId
);
void
Add
(
const
wxString
&
aLabel
,
int
aId
);
/**
* Function Add()
* 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.
* @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()
* Removes all the entries from the menu (as well as its title). It leaves the menu in the
* initial state.
*/
void
Clear
();
void
Clear
();
/**
* Function GetMenu()
* 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
///> events, it translates them to TOOL_EVENTs that may control tools.
class
CMEventHandler
:
public
wxEvtHandler
class
CMEventHandler
:
public
wxEvtHandler
{
{
public
:
public
:
///> Default constructor
///> 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.
void
onEvent
(
wxEvent
&
aEvent
);
void
onEvent
(
wxEvent
&
aEvent
);
private
:
private
:
///> 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()
* Sets a tool that is the creator of 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()
* 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 converted.
* @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.
wxMenu
m_menu
;
wxMenu
m_menu
;
///> Instance of menu event handler.
CMEventHandler
m_handler
;
CMEventHandler
m_handler
;
///> 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
...
...
include/tool/tool_base.h
View file @
3f320e4d
...
@@ -42,17 +42,21 @@ class VIEW_CONTROLS;
...
@@ -42,17 +42,21 @@ class VIEW_CONTROLS;
enum
TOOL_Type
enum
TOOL_Type
{
{
TOOL_Interactive
=
0x1
,
///> Tool that interacts with the user
TOOL_Batch
=
0x2
TOOL_Interactive
=
0x01
,
///> Tool that runs in the background without any user intervention
TOOL_Batch
=
0x02
};
};
/// Unique identifier for tools
typedef
int
TOOL_ID
;
typedef
int
TOOL_ID
;
typedef
DELEGATE
<
int
,
TOOL_EVENT
&>
TOOL_STATE_FUNC
;
typedef
DELEGATE
<
int
,
TOOL_EVENT
&>
TOOL_STATE_FUNC
;
/**
/**
* Class TOOL_BASE
* Class TOOL_BASE
*
*
* Base abstract interface for all kinds of tools
* Base abstract interface for all kinds of tools
.
*/
*/
class
TOOL_BASE
class
TOOL_BASE
...
@@ -61,25 +65,49 @@ public:
...
@@ -61,25 +65,49 @@ 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
){};
virtual
~
TOOL_BASE
()
{};
virtual
~
TOOL_BASE
()
{};
/**
* Function GetType()
* Returns 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()
* Returns the unique identifier of the tool. The identifier is set by an instance of
* TOOL_MANAGER.
* @return Identifier of the tool.
*/
TOOL_ID
GetId
()
const
TOOL_ID
GetId
()
const
{
{
return
m_toolId
;
return
m_toolId
;
}
}
/**
* Function GetName()
* Returns the name of the tool. Tool names are expected to obey the format:
* application.ToolName (eg. pcbnew.InteractiveSelection).
* @return The name of the tool.
*/
const
std
::
string
&
GetName
()
const
const
std
::
string
&
GetName
()
const
{
{
return
m_toolName
;
return
m_toolName
;
}
}
/**
* Function GetManager()
* 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
* NULL.
*/
TOOL_MANAGER
*
GetManager
()
const
TOOL_MANAGER
*
GetManager
()
const
{
{
return
m_toolMgr
;
return
m_toolMgr
;
...
@@ -96,14 +124,27 @@ protected:
...
@@ -96,14 +124,27 @@ protected:
*/
*/
void
attachManager
(
TOOL_MANAGER
*
aManager
);
void
attachManager
(
TOOL_MANAGER
*
aManager
);
/**
* Function getView()
*
* Returns the instance of VIEW object used in the application. It allows tools to draw.
* @return The instance of VIEW.
*/
KiGfx
::
VIEW
*
getView
()
const
;
KiGfx
::
VIEW
*
getView
()
const
;
/**
* Function getViewControls()
*
* 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.)
* @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, possibly with
* Returns the application window object, casted to requested user type.
* run-time type check
*/
*/
template
<
typename
T
>
template
<
typename
T
>
T
*
getEditFrame
()
const
T
*
getEditFrame
()
const
...
@@ -124,8 +165,14 @@ protected:
...
@@ -124,8 +165,14 @@ protected:
return
static_cast
<
T
*>
(
m
);
return
static_cast
<
T
*>
(
m
);
}
}
///> 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.
TOOL_ID
m_toolId
;
TOOL_ID
m_toolId
;
///> Name of the tool. Names are expected to obey the format application.ToolName
///> (eg. pcbnew.InteractiveSelection).
std
::
string
m_toolName
;
std
::
string
m_toolName
;
TOOL_MANAGER
*
m_toolMgr
;
TOOL_MANAGER
*
m_toolMgr
;
...
...
include/tool/tool_dispatcher.h
View file @
3f320e4d
...
@@ -29,7 +29,6 @@
...
@@ -29,7 +29,6 @@
#include <tool/tool_event.h>
#include <tool/tool_event.h>
//#include <wx/event.h>
#include <wx/kbdstate.h>
#include <wx/kbdstate.h>
class
TOOL_MANAGER
;
class
TOOL_MANAGER
;
...
@@ -61,26 +60,62 @@ public:
...
@@ -61,26 +60,62 @@ public:
TOOL_DISPATCHER
(
TOOL_MANAGER
*
aToolMgr
,
PCB_BASE_FRAME
*
aEditFrame
);
TOOL_DISPATCHER
(
TOOL_MANAGER
*
aToolMgr
,
PCB_BASE_FRAME
*
aEditFrame
);
virtual
~
TOOL_DISPATCHER
();
virtual
~
TOOL_DISPATCHER
();
/**
* Function ResetState()
* Brings the dispatcher to its initial state.
*/
virtual
void
ResetState
();
virtual
void
ResetState
();
/**
* Function DispatchWxEvent()
* Processes wxEvents (mostly UI events), translates them to TOOL_EVENTs, and makes tools
* handle those.
* @param aEvent is the wxWidgets event to be processed.
*/
virtual
void
DispatchWxEvent
(
wxEvent
&
aEvent
);
virtual
void
DispatchWxEvent
(
wxEvent
&
aEvent
);
virtual
void
DispatchWxCommand
(
wxCommandEvent
&
aEvent
);
/**
* Function DispatchWxCommand()
* Processes wxCommands (mostly menu related events) and runs appropriate actions (eg. run the
* specified tool).
* @param aEvent is the wxCommandEvent to be processed.
*/
virtual
void
DispatchWxCommand
(
const
wxCommandEvent
&
aEvent
);
private
:
private
:
///> Number of mouse buttons that is handled in events.
static
const
int
MouseButtonCount
=
3
;
static
const
int
MouseButtonCount
=
3
;
///> The time threshold for a mouse button press that distinguishes between a single mouse
///> click and a beginning of drag event (expressed in milliseconds).
static
const
int
DragTimeThreshold
=
300
;
static
const
int
DragTimeThreshold
=
300
;
///> The distance threshold for mouse cursor that disinguishes between a single mouse click
///> and a beginning of drag event (expressed in screen pixels).
static
const
int
DragDistanceThreshold
=
8
;
static
const
int
DragDistanceThreshold
=
8
;
///> Handles mouse related events (click, motion, dragging)
bool
handleMouseButton
(
wxEvent
&
aEvent
,
int
aIndex
,
bool
aMotion
);
bool
handleMouseButton
(
wxEvent
&
aEvent
,
int
aIndex
,
bool
aMotion
);
bool
handlePopupMenu
(
wxEvent
&
aEvent
);
///> Saves the state of key modifiers (Alt, Ctrl and so on).
int
decodeModifiers
(
const
wxKeyboardState
*
aState
)
const
;
int
decodeModifiers
(
const
wxKeyboardState
*
aState
)
const
;
///> Stores all the informations regarding a mouse button state.
struct
ButtonState
;
struct
ButtonState
;
///> The last mouse cursor position (in world coordinates).
VECTOR2D
m_lastMousePos
;
VECTOR2D
m_lastMousePos
;
///> State of mouse buttons.
std
::
vector
<
ButtonState
*>
m_buttons
;
std
::
vector
<
ButtonState
*>
m_buttons
;
///> Returns the instance of VIEW, used by the application.
KiGfx
::
VIEW
*
getView
();
KiGfx
::
VIEW
*
getView
();
///> Instance of tool manager that cooperates with the dispatcher.
TOOL_MANAGER
*
m_toolMgr
;
TOOL_MANAGER
*
m_toolMgr
;
///> Instance of wxFrame that is the source of UI events.
PCB_BASE_FRAME
*
m_editFrame
;
PCB_BASE_FRAME
*
m_editFrame
;
};
};
...
...
include/tool/tool_event.h
View file @
3f320e4d
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
#include <deque>
#include <deque>
#include <math/vector2d.h>
#include <math/vector2d.h>
#include <cassert>
#include <boost/optional.hpp>
#include <boost/optional.hpp>
...
@@ -71,17 +72,19 @@ enum TOOL_Actions
...
@@ -71,17 +72,19 @@ enum TOOL_Actions
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 the context menu.
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from
// the context menu.
TA_CancelTool
=
0x2000
,
TA_CancelTool
=
0x2000
,
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
over one of choices.
// Context menu update. Issued whenever context menu is open and the user hovers the mouse
//
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 closed it without selecting anything.
// Context menu choice. Sent if the user picked something from the context menu or
// closed it without selecting anything.
TA_ContextMenuChoice
=
0x8000
,
TA_ContextMenuChoice
=
0x8000
,
// Tool action
// Tool action
(allows to control tools)
TA_Action
=
0x10000
,
TA_Action
=
0x10000
,
TA_Any
=
0xffffffff
TA_Any
=
0xffffffff
...
@@ -129,6 +132,12 @@ enum CONTEXT_MENU_TRIGGER
...
@@ -129,6 +132,12 @@ enum CONTEXT_MENU_TRIGGER
class
TOOL_EVENT
class
TOOL_EVENT
{
{
public
:
public
:
/**
* Function Format()
* Returns information about event in form of a human-readable string.
*
* @return Event information.
*/
const
std
::
string
Format
()
const
;
const
std
::
string
Format
()
const
;
TOOL_EVENT
(
TOOL_EventCategory
aCategory
=
TC_None
,
TOOL_Actions
aAction
=
TA_None
,
TOOL_EVENT
(
TOOL_EventCategory
aCategory
=
TC_None
,
TOOL_Actions
aAction
=
TA_None
,
...
@@ -175,33 +184,44 @@ public:
...
@@ -175,33 +184,44 @@ public:
m_commandStr
=
aExtraParam
;
m_commandStr
=
aExtraParam
;
}
}
///> Returns the category (eg. mouse/keyboard/action) of an event..
TOOL_EventCategory
Category
()
const
TOOL_EventCategory
Category
()
const
{
{
return
m_category
;
return
m_category
;
}
}
///> Returns more specific information about the type of an event.
TOOL_Actions
Action
()
const
TOOL_Actions
Action
()
const
{
{
return
m_actions
;
return
m_actions
;
}
}
///> Returns information about difference between current mouse cursor position and the place
///> where dragging has started.
const
VECTOR2D
Delta
()
const
const
VECTOR2D
Delta
()
const
{
{
assert
(
m_category
==
TC_Mouse
);
// this should be used only with mouse events
return
m_mouseDelta
;
return
m_mouseDelta
;
}
}
///> Returns mouse cursor position in world coordinates.
const
VECTOR2D
&
Position
()
const
const
VECTOR2D
&
Position
()
const
{
{
assert
(
m_category
==
TC_Mouse
);
// this should be used only with mouse events
return
m_mousePos
;
return
m_mousePos
;
}
}
///> Returns the point where dragging has started.
const
VECTOR2D
&
DragOrigin
()
const
const
VECTOR2D
&
DragOrigin
()
const
{
{
assert
(
m_category
==
TC_Mouse
);
// this should be used only with mouse events
return
m_mouseDragOrigin
;
return
m_mouseDragOrigin
;
}
}
///> Returns information about mouse buttons state.
int
Buttons
()
const
int
Buttons
()
const
{
{
assert
(
m_category
==
TC_Mouse
);
// this should be used only with mouse events
return
m_mouseButtons
;
return
m_mouseButtons
;
}
}
...
@@ -231,6 +251,7 @@ public:
...
@@ -231,6 +251,7 @@ public:
return
m_actions
==
TA_CancelTool
;
return
m_actions
==
TA_CancelTool
;
}
}
///> Returns information about key modifiers state (Ctrl, Alt, etc.)
int
Modifier
(
int
aMask
=
MD_ModifierMask
)
const
int
Modifier
(
int
aMask
=
MD_ModifierMask
)
const
{
{
return
(
m_modifiers
&
aMask
);
return
(
m_modifiers
&
aMask
);
...
@@ -251,8 +272,6 @@ public:
...
@@ -251,8 +272,6 @@ public:
return
m_actions
==
TA_KeyDown
;
return
m_actions
==
TA_KeyDown
;
}
}
void
Ignore
();
void
SetMouseDragOrigin
(
const
VECTOR2D
&
aP
)
void
SetMouseDragOrigin
(
const
VECTOR2D
&
aP
)
{
{
m_mouseDragOrigin
=
aP
;
m_mouseDragOrigin
=
aP
;
...
@@ -268,6 +287,13 @@ public:
...
@@ -268,6 +287,13 @@ public:
m_mouseDelta
=
aP
;
m_mouseDelta
=
aP
;
}
}
/**
* Function Matches()
* Tests whether two events match in terms of category & action or command.
*
* @param aEvent is the event to test against.
* @return True if two events match, false otherwise.
*/
bool
Matches
(
const
TOOL_EVENT
&
aEvent
)
const
bool
Matches
(
const
TOOL_EVENT
&
aEvent
)
const
{
{
if
(
!
(
m_category
&
aEvent
.
m_category
)
)
if
(
!
(
m_category
&
aEvent
.
m_category
)
)
...
@@ -299,13 +325,25 @@ private:
...
@@ -299,13 +325,25 @@ private:
TOOL_Actions
m_actions
;
TOOL_Actions
m_actions
;
TOOL_ActionScope
m_scope
;
TOOL_ActionScope
m_scope
;
///> Difference between mouse cursor position and
///> the point where dragging event has started
VECTOR2D
m_mouseDelta
;
VECTOR2D
m_mouseDelta
;
///> Current mouse cursor position
VECTOR2D
m_mousePos
;
VECTOR2D
m_mousePos
;
///> Point where dragging has started
VECTOR2D
m_mouseDragOrigin
;
VECTOR2D
m_mouseDragOrigin
;
///> State of mouse buttons
int
m_mouseButtons
;
int
m_mouseButtons
;
///> Stores code of pressed/released key
int
m_keyCode
;
int
m_keyCode
;
///> State of key modifierts (Ctrl/Alt/etc.)
int
m_modifiers
;
int
m_modifiers
;
boost
::
optional
<
int
>
m_commandId
;
boost
::
optional
<
int
>
m_commandId
;
boost
::
optional
<
std
::
string
>
m_commandStr
;
boost
::
optional
<
std
::
string
>
m_commandStr
;
};
};
...
@@ -324,7 +362,10 @@ public:
...
@@ -324,7 +362,10 @@ public:
typedef
std
::
deque
<
TOOL_EVENT
>::
iterator
iterator
;
typedef
std
::
deque
<
TOOL_EVENT
>::
iterator
iterator
;
typedef
std
::
deque
<
TOOL_EVENT
>::
const_iterator
const_iterator
;
typedef
std
::
deque
<
TOOL_EVENT
>::
const_iterator
const_iterator
;
///> Default constructor. Creates an empty list.
TOOL_EVENT_LIST
()
{};
TOOL_EVENT_LIST
()
{};
///> Constructor for a list containing only one TOOL_EVENT.
TOOL_EVENT_LIST
(
const
TOOL_EVENT
&
aSingleEvent
)
TOOL_EVENT_LIST
(
const
TOOL_EVENT
&
aSingleEvent
)
{
{
m_events
.
push_back
(
aSingleEvent
);
m_events
.
push_back
(
aSingleEvent
);
...
@@ -346,6 +387,11 @@ public:
...
@@ -346,6 +387,11 @@ public:
return
boost
::
optional
<
const
TOOL_EVENT
&>
();
return
boost
::
optional
<
const
TOOL_EVENT
&>
();
}
}
/**
* Function Add()
* Adds a tool event to the list.
* @param aEvent is the tool event to be addded.
*/
void
Add
(
const
TOOL_EVENT
&
aEvent
)
void
Add
(
const
TOOL_EVENT
&
aEvent
)
{
{
m_events
.
push_back
(
aEvent
);
m_events
.
push_back
(
aEvent
);
...
...
include/tool/tool_interactive.h
View file @
3f320e4d
...
@@ -35,6 +35,10 @@ class CONTEXT_MENU;
...
@@ -35,6 +35,10 @@ class CONTEXT_MENU;
class
TOOL_INTERACTIVE
:
public
TOOL_BASE
class
TOOL_INTERACTIVE
:
public
TOOL_BASE
{
{
public
:
public
:
/**
* Constructor
*
* 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
);
/**
/**
...
@@ -46,8 +50,8 @@ public:
...
@@ -46,8 +50,8 @@ public:
/**
/**
* Function Reset()
* Function Reset()
* Brings the tool to a known, initial state. If the tool claimed anything from
the model or the view,
* Brings the tool to a known, initial state. If the tool claimed anything from
* 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
;
...
@@ -65,7 +69,9 @@ public:
...
@@ -65,7 +69,9 @@ public:
/**
/**
* 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 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
);
...
@@ -87,9 +93,8 @@ public:
...
@@ -87,9 +93,8 @@ public:
*/
*/
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 );
...
@@ -98,11 +103,10 @@ public:
...
@@ -98,11 +103,10 @@ public:
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
/* helper functions for constructing events for Wait() and Go() with less typing */
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
=
""
);
...
...
pcbnew/tools/move_tool.cpp
View file @
3f320e4d
...
@@ -36,6 +36,8 @@ using boost::optional;
...
@@ -36,6 +36,8 @@ using boost::optional;
MOVE_TOOL
::
MOVE_TOOL
()
:
MOVE_TOOL
::
MOVE_TOOL
()
:
TOOL_INTERACTIVE
(
"pcbnew.InteractiveMove"
),
m_selectionTool
(
NULL
),
TOOL_INTERACTIVE
(
"pcbnew.InteractiveMove"
),
m_selectionTool
(
NULL
),
// Available actions:
m_activate
(
m_toolName
,
AS_GLOBAL
,
'M'
,
"Move"
,
"Moves the selected item(s)"
),
m_activate
(
m_toolName
,
AS_GLOBAL
,
'M'
,
"Move"
,
"Moves the selected item(s)"
),
m_rotate
(
m_toolName
+
".rotate"
,
AS_CONTEXT
,
' '
,
"Rotate"
,
"Rotates selected item(s)"
),
m_rotate
(
m_toolName
+
".rotate"
,
AS_CONTEXT
,
' '
,
"Rotate"
,
"Rotates selected item(s)"
),
m_flip
(
m_toolName
+
".flip"
,
AS_CONTEXT
,
'F'
,
"Flip"
,
"Flips selected item(s)"
)
m_flip
(
m_toolName
+
".flip"
,
AS_CONTEXT
,
'F'
,
"Flip"
,
"Flips selected item(s)"
)
...
@@ -69,7 +71,7 @@ bool MOVE_TOOL::Init()
...
@@ -69,7 +71,7 @@ bool MOVE_TOOL::Init()
m_toolMgr
->
RegisterAction
(
&
m_rotate
);
m_toolMgr
->
RegisterAction
(
&
m_rotate
);
m_toolMgr
->
RegisterAction
(
&
m_flip
);
m_toolMgr
->
RegisterAction
(
&
m_flip
);
// Add context menu entries
for the selection tool
// Add context menu entries
that are displayed when selection tool is active
m_selectionTool
->
AddMenuItem
(
m_activate
);
m_selectionTool
->
AddMenuItem
(
m_activate
);
m_selectionTool
->
AddMenuItem
(
m_rotate
);
m_selectionTool
->
AddMenuItem
(
m_rotate
);
m_selectionTool
->
AddMenuItem
(
m_flip
);
m_selectionTool
->
AddMenuItem
(
m_flip
);
...
@@ -92,7 +94,9 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
...
@@ -92,7 +94,9 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
VIEW
*
view
=
getView
();
VIEW
*
view
=
getView
();
VIEW_CONTROLS
*
controls
=
getViewControls
();
VIEW_CONTROLS
*
controls
=
getViewControls
();
// Add a VIEW_GROUP that will hold all modified items
view
->
Add
(
&
m_items
);
view
->
Add
(
&
m_items
);
controls
->
ShowCursor
(
true
);
controls
->
ShowCursor
(
true
);
controls
->
SetSnapping
(
true
);
controls
->
SetSnapping
(
true
);
controls
->
SetAutoPan
(
true
);
controls
->
SetAutoPan
(
true
);
...
@@ -102,7 +106,7 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
...
@@ -102,7 +106,7 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
{
{
if
(
evt
->
IsCancel
()
)
if
(
evt
->
IsCancel
()
)
{
{
restore
=
true
;
restore
=
true
;
// Cancelling the tool means that items have to be restored
break
;
// Finish
break
;
// Finish
}
}
...
@@ -111,12 +115,12 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
...
@@ -111,12 +115,12 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
{
{
VECTOR2D
cursorPos
=
getView
()
->
ToWorld
(
getViewControls
()
->
GetCursorPosition
()
);
VECTOR2D
cursorPos
=
getView
()
->
ToWorld
(
getViewControls
()
->
GetCursorPosition
()
);
if
(
evt
->
Matches
(
m_rotate
.
GetEvent
()
)
)
if
(
evt
->
Matches
(
m_rotate
.
GetEvent
()
)
)
// got rotation event?
{
{
m_state
.
Rotate
(
cursorPos
,
900.0
);
m_state
.
Rotate
(
cursorPos
,
900.0
);
m_items
.
ViewUpdate
(
VIEW_ITEM
::
GEOMETRY
);
m_items
.
ViewUpdate
(
VIEW_ITEM
::
GEOMETRY
);
}
}
else
if
(
evt
->
Matches
(
m_flip
.
GetEvent
()
)
)
else
if
(
evt
->
Matches
(
m_flip
.
GetEvent
()
)
)
// got flip event?
{
{
m_state
.
Flip
(
cursorPos
);
m_state
.
Flip
(
cursorPos
);
m_items
.
ViewUpdate
(
VIEW_ITEM
::
GEOMETRY
);
m_items
.
ViewUpdate
(
VIEW_ITEM
::
GEOMETRY
);
...
@@ -165,20 +169,22 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
...
@@ -165,20 +169,22 @@ int MOVE_TOOL::Main( TOOL_EVENT& aEvent )
// Restore visibility of the original items
// Restore visibility of the original items
vgSetVisibility
(
&
m_items
,
true
);
vgSetVisibility
(
&
m_items
,
true
);
// Movement has to be rollbacked, so restore the previous state of items
if
(
restore
)
if
(
restore
)
{
{
// Modifications has to be rollbacked, so restore the previous state of items
vgUpdate
(
&
m_items
,
VIEW_ITEM
::
APPEARANCE
);
vgUpdate
(
&
m_items
,
VIEW_ITEM
::
APPEARANCE
);
m_state
.
RestoreAll
();
m_state
.
RestoreAll
();
}
}
else
else
{
{
// Changes are applied, so update the items
vgUpdate
(
&
m_items
,
m_state
.
GetUpdateFlag
()
);
vgUpdate
(
&
m_items
,
m_state
.
GetUpdateFlag
()
);
m_state
.
Apply
();
m_state
.
Apply
();
}
}
m_items
.
Clear
();
m_items
.
Clear
();
view
->
Remove
(
&
m_items
);
view
->
Remove
(
&
m_items
);
controls
->
ShowCursor
(
false
);
controls
->
ShowCursor
(
false
);
controls
->
SetSnapping
(
false
);
controls
->
SetSnapping
(
false
);
controls
->
SetAutoPan
(
false
);
controls
->
SetAutoPan
(
false
);
...
...
pcbnew/tools/selection_area.h
View file @
3f320e4d
...
@@ -50,6 +50,7 @@ public:
...
@@ -50,6 +50,7 @@ public:
virtual
const
BOX2I
ViewBBox
()
const
;
virtual
const
BOX2I
ViewBBox
()
const
;
void
ViewDraw
(
int
aLayer
,
KiGfx
::
GAL
*
aGal
)
const
;
void
ViewDraw
(
int
aLayer
,
KiGfx
::
GAL
*
aGal
)
const
;
void
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
;
void
ViewGetLayers
(
int
aLayers
[],
int
&
aCount
)
const
;
void
SetOrigin
(
VECTOR2I
aOrigin
)
void
SetOrigin
(
VECTOR2I
aOrigin
)
...
...
pcbnew/tools/selection_tool.cpp
View file @
3f320e4d
...
@@ -83,7 +83,6 @@ bool SELECTION_TOOL::Init()
...
@@ -83,7 +83,6 @@ bool SELECTION_TOOL::Init()
int
SELECTION_TOOL
::
Main
(
TOOL_EVENT
&
aEvent
)
int
SELECTION_TOOL
::
Main
(
TOOL_EVENT
&
aEvent
)
{
{
BOARD
*
board
=
getModel
<
BOARD
>
(
PCB_T
);
BOARD
*
board
=
getModel
<
BOARD
>
(
PCB_T
);
assert
(
board
!=
NULL
);
assert
(
board
!=
NULL
);
// Main loop: keep receiving events
// Main loop: keep receiving events
...
@@ -116,13 +115,16 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
...
@@ -116,13 +115,16 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
}
}
else
else
{
{
// Check if dragging has started within any of selected items bounding box
if
(
containsSelected
(
evt
->
Position
()
)
)
if
(
containsSelected
(
evt
->
Position
()
)
)
{
{
// Yes -> run the move tool and wait till it finishes
m_toolMgr
->
InvokeTool
(
"pcbnew.InteractiveMove"
);
m_toolMgr
->
InvokeTool
(
"pcbnew.InteractiveMove"
);
Wait
();
Wait
();
}
}
else
else
{
{
// No -> clear the selection list
clearSelection
();
clearSelection
();
}
}
}
}
...
@@ -135,7 +137,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
...
@@ -135,7 +137,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent )
void
SELECTION_TOOL
::
AddMenuItem
(
const
TOOL_ACTION
&
aAction
)
void
SELECTION_TOOL
::
AddMenuItem
(
const
TOOL_ACTION
&
aAction
)
{
{
assert
(
aAction
.
GetId
()
>
0
);
// Check if the action was registered before
assert
(
aAction
.
GetId
()
>
0
);
// Check if the action was registered before
in ACTION_MANAGER
m_menu
.
Add
(
aAction
);
m_menu
.
Add
(
aAction
);
}
}
...
@@ -259,9 +261,9 @@ BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector
...
@@ -259,9 +261,9 @@ BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector
bool
SELECTION_TOOL
::
selectMultiple
()
bool
SELECTION_TOOL
::
selectMultiple
()
{
{
VIEW
*
view
=
getView
();
bool
cancelled
=
false
;
// Was the tool cancelled while it was running?
bool
cancelled
=
false
;
m_multiple
=
true
;
// Multiple selection mode is active
m_multiple
=
true
;
// Multiple selection mode is active
VIEW
*
view
=
getView
();
getViewControls
()
->
SetAutoPan
(
true
);
getViewControls
()
->
SetAutoPan
(
true
);
// Those 2 lines remove the blink-in-the-random-place effect
// Those 2 lines remove the blink-in-the-random-place effect
...
@@ -291,7 +293,7 @@ bool SELECTION_TOOL::selectMultiple()
...
@@ -291,7 +293,7 @@ bool SELECTION_TOOL::selectMultiple()
if
(
evt
->
IsMouseUp
(
MB_Left
)
)
if
(
evt
->
IsMouseUp
(
MB_Left
)
)
{
{
// End drawing
a
selection box
// End drawing
the
selection box
m_selArea
->
ViewSetVisible
(
false
);
m_selArea
->
ViewSetVisible
(
false
);
// Mark items within the selection box as selected
// Mark items within the selection box as selected
...
@@ -315,6 +317,7 @@ bool SELECTION_TOOL::selectMultiple()
...
@@ -315,6 +317,7 @@ bool SELECTION_TOOL::selectMultiple()
// Now the context menu should be enabled
// Now the context menu should be enabled
if
(
!
m_selectedItems
.
empty
()
)
if
(
!
m_selectedItems
.
empty
()
)
SetContextMenu
(
&
m_menu
,
CMENU_BUTTON
);
SetContextMenu
(
&
m_menu
,
CMENU_BUTTON
);
break
;
break
;
}
}
}
}
...
@@ -367,6 +370,7 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
...
@@ -367,6 +370,7 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
{
{
optional
<
int
>
id
=
evt
->
GetCommandId
();
optional
<
int
>
id
=
evt
->
GetCommandId
();
// User has selected an item, so this one will be returned
if
(
id
&&
(
*
id
>=
0
)
)
if
(
id
&&
(
*
id
>=
0
)
)
current
=
(
*
aCollector
)[
*
id
];
current
=
(
*
aCollector
)[
*
id
];
...
@@ -392,11 +396,12 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
...
@@ -392,11 +396,12 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector )
bool
SELECTION_TOOL
::
selectable
(
const
BOARD_ITEM
*
aItem
)
const
bool
SELECTION_TOOL
::
selectable
(
const
BOARD_ITEM
*
aItem
)
const
{
{
// Is high contrast mode enabled?
bool
highContrast
=
getView
()
->
GetPainter
()
->
GetSettings
()
->
GetHighContrast
();
bool
highContrast
=
getView
()
->
GetPainter
()
->
GetSettings
()
->
GetHighContrast
();
if
(
highContrast
)
if
(
highContrast
)
{
{
bool
onActive
=
false
;
bool
onActive
=
false
;
// Is the item on any of active layers?
int
layers
[
KiGfx
::
VIEW
::
VIEW_MAX_LAYERS
],
layers_count
;
int
layers
[
KiGfx
::
VIEW
::
VIEW_MAX_LAYERS
],
layers_count
;
// Filter out items that do not belong to active layers
// Filter out items that do not belong to active layers
...
@@ -406,14 +411,14 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
...
@@ -406,14 +411,14 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
for
(
int
i
=
0
;
i
<
layers_count
;
++
i
)
for
(
int
i
=
0
;
i
<
layers_count
;
++
i
)
{
{
if
(
activeLayers
.
count
(
layers
[
i
]
)
>
0
)
// Item is on at least one
active layer
if
(
activeLayers
.
count
(
layers
[
i
]
)
>
0
)
// Item is on at least one
of active layers
{
{
onActive
=
true
;
onActive
=
true
;
break
;
break
;
}
}
}
}
if
(
!
onActive
)
if
(
!
onActive
)
// We do not want to select items that are in the background
return
false
;
return
false
;
}
}
...
@@ -426,8 +431,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
...
@@ -426,8 +431,7 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const
LAYER_NUM
top
,
bottom
;
LAYER_NUM
top
,
bottom
;
static_cast
<
const
SEGVIA
*>
(
aItem
)
->
ReturnLayerPair
(
&
top
,
&
bottom
);
static_cast
<
const
SEGVIA
*>
(
aItem
)
->
ReturnLayerPair
(
&
top
,
&
bottom
);
return
(
board
->
IsLayerVisible
(
top
)
||
return
(
board
->
IsLayerVisible
(
top
)
||
board
->
IsLayerVisible
(
bottom
)
);
board
->
IsLayerVisible
(
bottom
)
);
}
}
break
;
break
;
...
@@ -473,8 +477,7 @@ bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const
...
@@ -473,8 +477,7 @@ bool SELECTION_TOOL::containsSelected( const VECTOR2I& aPoint ) const
{
{
// Check if the point is located within any of the currently selected items bounding boxes
// Check if the point is located within any of the currently selected items bounding boxes
std
::
set
<
BOARD_ITEM
*>::
iterator
it
,
it_end
;
std
::
set
<
BOARD_ITEM
*>::
iterator
it
,
it_end
;
for
(
it
=
m_selectedItems
.
begin
(),
it_end
=
m_selectedItems
.
end
();
for
(
it
=
m_selectedItems
.
begin
(),
it_end
=
m_selectedItems
.
end
();
it
!=
it_end
;
++
it
)
it
!=
it_end
;
++
it
)
{
{
BOX2I
itemBox
=
(
*
it
)
->
ViewBBox
();
BOX2I
itemBox
=
(
*
it
)
->
ViewBBox
();
itemBox
.
Inflate
(
500000
);
// Give some margin for gripping an item
itemBox
.
Inflate
(
500000
);
// Give some margin for gripping an item
...
...
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