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
ad1b138f
Commit
ad1b138f
authored
May 16, 2014
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reformatted PNS code to conform the coding policy.
parent
ebf35fd4
Changes
44
Show whitespace changes
Inline
Side-by-side
Showing
44 changed files
with
1930 additions
and
1785 deletions
+1930
-1785
direction.h
pcbnew/router/direction.h
+16
-18
pns_algo_base.h
pcbnew/router/pns_algo_base.h
+8
-7
pns_dragger.cpp
pcbnew/router/pns_dragger.cpp
+79
-61
pns_dragger.h
pcbnew/router/pns_dragger.h
+26
-31
pns_index.h
pcbnew/router/pns_index.h
+19
-23
pns_item.cpp
pcbnew/router/pns_item.cpp
+1
-3
pns_item.h
pcbnew/router/pns_item.h
+9
-11
pns_itemset.cpp
pcbnew/router/pns_itemset.cpp
+20
-15
pns_itemset.h
pcbnew/router/pns_itemset.h
+14
-13
pns_joint.h
pcbnew/router/pns_joint.h
+37
-35
pns_layerset.h
pcbnew/router/pns_layerset.h
+6
-6
pns_line.cpp
pcbnew/router/pns_line.cpp
+252
-202
pns_line.h
pcbnew/router/pns_line.h
+29
-29
pns_line_placer.cpp
pcbnew/router/pns_line_placer.cpp
+115
-97
pns_line_placer.h
pcbnew/router/pns_line_placer.h
+11
-15
pns_logger.cpp
pcbnew/router/pns_logger.cpp
+57
-40
pns_logger.h
pcbnew/router/pns_logger.h
+11
-10
pns_node.cpp
pcbnew/router/pns_node.cpp
+215
-194
pns_node.h
pcbnew/router/pns_node.h
+59
-66
pns_optimizer.cpp
pcbnew/router/pns_optimizer.cpp
+62
-72
pns_optimizer.h
pcbnew/router/pns_optimizer.h
+17
-21
pns_router.cpp
pcbnew/router/pns_router.cpp
+149
-139
pns_router.h
pcbnew/router/pns_router.h
+25
-22
pns_routing_settings.cpp
pcbnew/router/pns_routing_settings.cpp
+3
-1
pns_routing_settings.h
pcbnew/router/pns_routing_settings.h
+7
-8
pns_segment.h
pcbnew/router/pns_segment.h
+6
-7
pns_shove.cpp
pcbnew/router/pns_shove.cpp
+344
-301
pns_shove.h
pcbnew/router/pns_shove.h
+42
-40
pns_solid.cpp
pcbnew/router/pns_solid.cpp
+17
-17
pns_solid.h
pcbnew/router/pns_solid.h
+2
-3
pns_utils.cpp
pcbnew/router/pns_utils.cpp
+12
-13
pns_utils.h
pcbnew/router/pns_utils.h
+3
-4
pns_via.cpp
pcbnew/router/pns_via.cpp
+12
-15
pns_via.h
pcbnew/router/pns_via.h
+13
-13
pns_walkaround.cpp
pcbnew/router/pns_walkaround.cpp
+32
-37
pns_walkaround.h
pcbnew/router/pns_walkaround.h
+20
-19
range.h
pcbnew/router/range.h
+25
-23
router_preview_item.cpp
pcbnew/router/router_preview_item.cpp
+67
-68
router_preview_item.h
pcbnew/router/router_preview_item.h
+6
-7
router_tool.cpp
pcbnew/router/router_tool.cpp
+63
-61
router_tool.h
pcbnew/router/router_tool.h
+1
-3
time_limit.cpp
pcbnew/router/time_limit.cpp
+10
-5
time_limit.h
pcbnew/router/time_limit.h
+6
-8
trace.h
pcbnew/router/trace.h
+2
-2
No files found.
pcbnew/router/direction.h
View file @
ad1b138f
...
...
@@ -209,12 +209,12 @@ public:
// we are more horizontal than vertical?
if
(
w
>
h
)
{
mp0
=
VECTOR2I
(
(
w
-
h
)
*
sw
,
0
);
// direction: E
mp0
=
VECTOR2I
(
(
w
-
h
)
*
sw
,
0
);
// direction: E
mp1
=
VECTOR2I
(
h
*
sw
,
h
*
sh
);
// direction: NE
}
else
{
mp0
=
VECTOR2I
(
0
,
sh
*
(
h
-
w
)
);
// direction: N
mp0
=
VECTOR2I
(
0
,
sh
*
(
h
-
w
)
);
// direction: N
mp1
=
VECTOR2I
(
sw
*
w
,
sh
*
w
);
// direction: NE
}
...
...
@@ -237,7 +237,7 @@ public:
pl
.
Append
(
aP1
);
pl
.
Simplify
();
return
pl
;
}
;
}
bool
operator
==
(
const
DIRECTION_45
&
aOther
)
const
{
...
...
@@ -275,19 +275,17 @@ public:
{
DIRECTION_45
l
;
if
(
m_dir
==
UNDEFINED
)
if
(
m_dir
==
UNDEFINED
)
return
l
;
if
(
m_dir
==
N
)
if
(
m_dir
==
N
)
l
.
m_dir
=
NW
;
else
l
.
m_dir
=
static_cast
<
Directions
>
(
m_dir
-
1
);
l
.
m_dir
=
static_cast
<
Directions
>
(
m_dir
-
1
);
return
l
;
}
/**
* Function ToVector()
*
...
...
@@ -295,19 +293,19 @@ public:
*/
const
VECTOR2I
ToVector
()
const
{
switch
(
m_dir
)
switch
(
m_dir
)
{
case
N
:
return
VECTOR2I
(
0
,
1
);
case
S
:
return
VECTOR2I
(
0
,
-
1
);
case
E
:
return
VECTOR2I
(
1
,
0
);
case
W
:
return
VECTOR2I
(
-
1
,
0
);
case
NE
:
return
VECTOR2I
(
1
,
1
);
case
NW
:
return
VECTOR2I
(
-
1
,
1
);
case
SE
:
return
VECTOR2I
(
1
,
-
1
);
case
SW
:
return
VECTOR2I
(
-
1
,
-
1
);
case
N
:
return
VECTOR2I
(
0
,
1
);
case
S
:
return
VECTOR2I
(
0
,
-
1
);
case
E
:
return
VECTOR2I
(
1
,
0
);
case
W
:
return
VECTOR2I
(
-
1
,
0
);
case
NE
:
return
VECTOR2I
(
1
,
1
);
case
NW
:
return
VECTOR2I
(
-
1
,
1
);
case
SE
:
return
VECTOR2I
(
1
,
-
1
);
case
SW
:
return
VECTOR2I
(
-
1
,
-
1
);
default
:
return
VECTOR2I
(
0
,
0
);
return
VECTOR2I
(
0
,
0
);
}
}
...
...
pcbnew/router/pns_algo_base.h
View file @
ad1b138f
...
...
@@ -33,17 +33,18 @@ class PNS_LOGGER;
* Holds a bunch of objects commonly used by all algorithms (P&S settings, parent router instance, logging)
**/
class
PNS_ALGO_BASE
{
class
PNS_ALGO_BASE
{
public
:
PNS_ALGO_BASE
(
PNS_ROUTER
*
aRouter
)
:
PNS_ALGO_BASE
(
PNS_ROUTER
*
aRouter
)
:
m_router
(
aRouter
)
{};
{}
virtual
~
PNS_ALGO_BASE
()
{}
///> Returns the instance of our router
PNS_ROUTER
*
Router
()
const
{
PNS_ROUTER
*
Router
()
const
{
return
m_router
;
}
...
...
@@ -51,10 +52,10 @@ public:
PNS_ROUTING_SETTINGS
&
Settings
()
const
;
///> Returns the logger object, allowing to dump geometry to a file.
virtual
PNS_LOGGER
*
Logger
();
virtual
PNS_LOGGER
*
Logger
();
private
:
PNS_ROUTER
*
m_router
;
PNS_ROUTER
*
m_router
;
};
#endif
pcbnew/router/pns_dragger.cpp
View file @
ad1b138f
...
...
@@ -29,7 +29,8 @@ PNS_DRAGGER::PNS_DRAGGER( PNS_ROUTER* aRouter ) :
{
m_world
=
NULL
;
m_shove
=
NULL
;
};
}
PNS_DRAGGER
::~
PNS_DRAGGER
()
{
...
...
@@ -37,97 +38,103 @@ PNS_DRAGGER::~PNS_DRAGGER()
delete
m_shove
;
}
void
PNS_DRAGGER
::
SetWorld
(
PNS_NODE
*
aWorld
)
void
PNS_DRAGGER
::
SetWorld
(
PNS_NODE
*
aWorld
)
{
m_world
=
aWorld
;
}
bool
PNS_DRAGGER
::
startDragSegment
(
const
VECTOR2D
&
aP
,
PNS_SEGMENT
*
aSeg
)
bool
PNS_DRAGGER
::
startDragSegment
(
const
VECTOR2D
&
aP
,
PNS_SEGMENT
*
aSeg
)
{
int
w2
=
aSeg
->
Width
()
/
2
;
m_draggedLine
=
m_world
->
AssembleLine
(
aSeg
,
&
m_draggedSegmentIndex
);
m_shove
->
SetInitialLine
(
m_draggedLine
);
m_shove
->
SetInitialLine
(
m_draggedLine
);
m_lastValidDraggedLine
=
*
m_draggedLine
;
m_lastValidDraggedLine
.
ClearSegmentLinks
();
if
(
(
aP
-
aSeg
->
Seg
().
A
).
EuclideanNorm
()
<=
w2
)
if
(
(
aP
-
aSeg
->
Seg
().
A
).
EuclideanNorm
()
<=
w2
)
m_mode
=
CORNER
;
else
if
(
(
aP
-
aSeg
->
Seg
().
B
).
EuclideanNorm
()
<=
w2
)
else
if
(
(
aP
-
aSeg
->
Seg
().
B
).
EuclideanNorm
()
<=
w2
)
{
m_draggedSegmentIndex
++
;
m_mode
=
CORNER
;
}
else
m_mode
=
SEGMENT
;
return
true
;
}
bool
PNS_DRAGGER
::
startDragVia
(
const
VECTOR2D
&
aP
,
PNS_VIA
*
aVia
)
bool
PNS_DRAGGER
::
startDragVia
(
const
VECTOR2D
&
aP
,
PNS_VIA
*
aVia
)
{
m_draggedVia
=
aVia
;
m_initialVia
=
aVia
;
m_mode
=
VIA
;
VECTOR2I
p0
(
aVia
->
Pos
()
);
VECTOR2I
p0
(
aVia
->
Pos
()
);
PNS_JOINT
*
jt
=
m_world
->
FindJoint
(
p0
,
aVia
->
Layers
().
Start
(),
aVia
->
Net
()
);
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jt
->
LinkList
()
)
{
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
)
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
)
{
int
segIndex
;
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
item
;
std
::
auto_ptr
<
PNS_LINE
>
l
(
m_world
->
AssembleLine
(
seg
,
&
segIndex
)
);
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
item
;
std
::
auto_ptr
<
PNS_LINE
>
l
(
m_world
->
AssembleLine
(
seg
,
&
segIndex
)
);
if
(
segIndex
!=
0
)
if
(
segIndex
!=
0
)
l
->
Reverse
();
m_origViaConnections
.
push_back
(
*
l
);
m_origViaConnections
.
push_back
(
*
l
);
}
}
return
true
;
}
bool
PNS_DRAGGER
::
Start
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aStartItem
)
bool
PNS_DRAGGER
::
Start
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aStartItem
)
{
m_shove
=
new
PNS_SHOVE
(
m_world
,
Router
()
);
m_shove
=
new
PNS_SHOVE
(
m_world
,
Router
()
);
m_lastNode
=
NULL
;
m_draggedItems
.
Clear
();
m_currentMode
=
Settings
().
Mode
();
TRACE
(
2
,
"StartDragging: item %p [kind %d]"
,
aStartItem
%
aStartItem
->
Kind
()
);
TRACE
(
2
,
"StartDragging: item %p [kind %d]"
,
aStartItem
%
aStartItem
->
Kind
()
);
switch
(
aStartItem
->
Kind
()
)
{
case
PNS_ITEM
:
:
SEGMENT
:
return
startDragSegment
(
aP
,
static_cast
<
PNS_SEGMENT
*>
(
aStartItem
)
);
return
startDragSegment
(
aP
,
static_cast
<
PNS_SEGMENT
*>
(
aStartItem
)
);
case
PNS_ITEM
:
:
VIA
:
return
startDragVia
(
aP
,
static_cast
<
PNS_VIA
*>
(
aStartItem
)
);
default
:
return
false
;
}
}
bool
PNS_DRAGGER
::
dragMarkObstacles
(
const
VECTOR2I
&
aP
)
bool
PNS_DRAGGER
::
dragMarkObstacles
(
const
VECTOR2I
&
aP
)
{
if
(
m_lastNode
)
if
(
m_lastNode
)
{
delete
m_lastNode
;
m_lastNode
=
NULL
;
}
switch
(
m_mode
)
switch
(
m_mode
)
{
case
SEGMENT
:
case
CORNER
:
{
int
thresh
=
Settings
().
SmoothDraggedSegments
()
?
m_draggedLine
->
Width
()
/
4
:
0
;
PNS_LINE
tmp
(
*
m_draggedLine
);
PNS_LINE
tmp
(
*
m_draggedLine
);
if
(
m_mode
==
SEGMENT
)
if
(
m_mode
==
SEGMENT
)
tmp
.
DragSegment
(
aP
,
m_draggedSegmentIndex
,
thresh
);
else
tmp
.
DragCorner
(
aP
,
m_draggedSegmentIndex
,
thresh
);
...
...
@@ -143,17 +150,17 @@ bool PNS_DRAGGER::dragMarkObstacles(const VECTOR2I& aP)
break
;
}
case
VIA
:
// fixme...
{
m_lastNode
=
m_shove
->
CurrentNode
()
->
Branch
();
dumbDragVia
(
m_initialVia
,
m_lastNode
,
aP
);
break
;
}
}
if
(
Settings
().
CanViolateDRC
()
)
if
(
Settings
().
CanViolateDRC
()
)
m_dragStatus
=
true
;
else
m_dragStatus
=
!
m_world
->
CheckColliding
(
m_draggedItems
);
...
...
@@ -161,60 +168,62 @@ bool PNS_DRAGGER::dragMarkObstacles(const VECTOR2I& aP)
return
true
;
}
void
PNS_DRAGGER
::
dumbDragVia
(
PNS_VIA
*
aVia
,
PNS_NODE
*
aNode
,
const
VECTOR2I
&
aP
)
void
PNS_DRAGGER
::
dumbDragVia
(
PNS_VIA
*
aVia
,
PNS_NODE
*
aNode
,
const
VECTOR2I
&
aP
)
{
// fixme: this is awful.
m_draggedVia
=
aVia
->
Clone
();
m_draggedVia
->
SetPos
(
aP
);
m_draggedItems
.
Clear
();
m_draggedItems
.
Add
(
m_draggedVia
);
m_draggedItems
.
Add
(
m_draggedVia
);
m_lastNode
->
Remove
(
aVia
);
m_lastNode
->
Add
(
m_draggedVia
);
m_lastNode
->
Remove
(
aVia
);
m_lastNode
->
Add
(
m_draggedVia
);
BOOST_FOREACH
(
PNS_LINE
&
l
,
m_origViaConnections
)
BOOST_FOREACH
(
PNS_LINE
&
l
,
m_origViaConnections
)
{
PNS_LINE
origLine
(
l
);
PNS_LINE
*
draggedLine
=
l
.
Clone
();
PNS_LINE
*
draggedLine
=
l
.
Clone
();
draggedLine
->
DragCorner
(
aP
,
0
);
draggedLine
->
ClearSegmentLinks
();
m_draggedItems
.
AddOwned
(
draggedLine
);
m_lastNode
->
Remove
(
&
origLine
);
m_lastNode
->
Add
(
draggedLine
);
m_lastNode
->
Remove
(
&
origLine
);
m_lastNode
->
Add
(
draggedLine
);
}
}
bool
PNS_DRAGGER
::
dragShove
(
const
VECTOR2I
&
aP
)
bool
PNS_DRAGGER
::
dragShove
(
const
VECTOR2I
&
aP
)
{
bool
ok
=
false
;
if
(
m_lastNode
)
if
(
m_lastNode
)
{
delete
m_lastNode
;
m_lastNode
=
NULL
;
}
switch
(
m_mode
)
switch
(
m_mode
)
{
case
SEGMENT
:
case
CORNER
:
{
int
thresh
=
Settings
().
SmoothDraggedSegments
()
?
m_draggedLine
->
Width
()
/
4
:
0
;
PNS_LINE
tmp
(
*
m_draggedLine
);
if
(
m_mode
==
SEGMENT
)
tmp
.
DragSegment
(
aP
,
m_draggedSegmentIndex
,
thresh
);
PNS_LINE
tmp
(
*
m_draggedLine
);
if
(
m_mode
==
SEGMENT
)
tmp
.
DragSegment
(
aP
,
m_draggedSegmentIndex
,
thresh
);
else
tmp
.
DragCorner
(
aP
,
m_draggedSegmentIndex
,
thresh
);
tmp
.
DragCorner
(
aP
,
m_draggedSegmentIndex
,
thresh
);
PNS_SHOVE
::
S
hoveStatus
st
=
m_shove
->
ShoveLines
(
tmp
);
PNS_SHOVE
::
S
HOVE_STATUS
st
=
m_shove
->
ShoveLines
(
tmp
);
if
(
st
==
PNS_SHOVE
::
SH_OK
)
if
(
st
==
PNS_SHOVE
::
SH_OK
)
ok
=
true
;
else
if
(
st
==
PNS_SHOVE
::
SH_HEAD_MODIFIED
)
else
if
(
st
==
PNS_SHOVE
::
SH_HEAD_MODIFIED
)
{
tmp
=
m_shove
->
NewHead
();
ok
=
true
;
...
...
@@ -222,22 +231,23 @@ bool PNS_DRAGGER::dragShove(const VECTOR2I& aP)
m_lastNode
=
m_shove
->
CurrentNode
()
->
Branch
();
if
(
ok
)
if
(
ok
)
m_lastValidDraggedLine
=
tmp
;
m_lastValidDraggedLine
.
ClearSegmentLinks
();
m_lastValidDraggedLine
.
Unmark
();
m_lastNode
->
Add
(
&
m_lastValidDraggedLine
);
m_draggedItems
=
PNS_ITEMSET
(
&
m_lastValidDraggedLine
);
m_lastNode
->
Add
(
&
m_lastValidDraggedLine
);
m_draggedItems
=
PNS_ITEMSET
(
&
m_lastValidDraggedLine
);
break
;
}
case
VIA
:
{
PNS_VIA
*
newVia
;
PNS_SHOVE
::
S
hoveStatus
st
=
m_shove
->
ShoveDraggingVia
(
m_draggedVia
,
aP
,
&
newVia
);
PNS_SHOVE
::
S
HOVE_STATUS
st
=
m_shove
->
ShoveDraggingVia
(
m_draggedVia
,
aP
,
&
newVia
);
if
(
st
==
PNS_SHOVE
::
SH_OK
||
st
==
PNS_SHOVE
::
SH_HEAD_MODIFIED
)
if
(
st
==
PNS_SHOVE
::
SH_OK
||
st
==
PNS_SHOVE
::
SH_HEAD_MODIFIED
)
ok
=
true
;
m_lastNode
=
m_shove
->
CurrentNode
()
->
Branch
();
...
...
@@ -250,16 +260,17 @@ bool PNS_DRAGGER::dragShove(const VECTOR2I& aP)
break
;
}
}
m_dragStatus
=
ok
;
return
ok
;
}
bool
PNS_DRAGGER
::
FixRoute
(
)
bool
PNS_DRAGGER
::
FixRoute
()
{
if
(
m_dragStatus
)
if
(
m_dragStatus
)
{
Router
()
->
CommitRouting
(
CurrentNode
()
);
return
true
;
...
...
@@ -268,34 +279,41 @@ bool PNS_DRAGGER::FixRoute( )
return
false
;
}
bool
PNS_DRAGGER
::
Drag
(
const
VECTOR2I
&
aP
)
bool
PNS_DRAGGER
::
Drag
(
const
VECTOR2I
&
aP
)
{
switch
(
m_currentMode
)
switch
(
m_currentMode
)
{
case
RM_MarkObstacles
:
return
dragMarkObstacles
(
aP
);
return
dragMarkObstacles
(
aP
);
case
RM_Shove
:
case
RM_Walkaround
:
case
RM_Smart
:
return
dragShove
(
aP
);
return
dragShove
(
aP
);
default
:
return
false
;
}
}
PNS_NODE
*
PNS_DRAGGER
::
CurrentNode
()
const
{
return
m_lastNode
;
}
const
PNS_ITEMSET
PNS_DRAGGER
::
Traces
()
{
return
m_draggedItems
;
}
PNS_LOGGER
*
PNS_DRAGGER
::
Logger
()
PNS_LOGGER
*
PNS_DRAGGER
::
Logger
()
{
if
(
m_shove
)
if
(
m_shove
)
return
m_shove
->
Logger
();
return
NULL
;
}
pcbnew/router/pns_dragger.h
View file @
ad1b138f
...
...
@@ -39,12 +39,10 @@ class PNS_ROUTER_BASE;
*
* Via, segment and corner dragging algorithm.
*/
class
PNS_DRAGGER
:
public
PNS_ALGO_BASE
{
public
:
PNS_DRAGGER
(
PNS_ROUTER
*
aRouter
);
PNS_DRAGGER
(
PNS_ROUTER
*
aRouter
);
~
PNS_DRAGGER
();
/**
...
...
@@ -52,8 +50,7 @@ public:
*
* Sets the board to work on.
*/
void
SetWorld
(
PNS_NODE
*
aWorld
);
void
SetWorld
(
PNS_NODE
*
aWorld
);
/**
* Function Start()
...
...
@@ -61,7 +58,7 @@ public:
* Starts routing a single track at point aP, taking item aStartItem as anchor
* (unless NULL). Returns true if a dragging operation has started.
*/
bool
Start
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aStartItem
);
bool
Start
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aStartItem
);
/**
* Function Drag()
...
...
@@ -69,7 +66,7 @@ public:
* Drags the current segment/corner/via to the point aP.
* @return true, if dragging finished with success.
*/
bool
Drag
(
const
VECTOR2I
&
aP
);
bool
Drag
(
const
VECTOR2I
&
aP
);
/**
* Function FixRoute()
...
...
@@ -78,7 +75,7 @@ public:
* and eventually commits it to the world.
* @return true, if dragging finished with success.
*/
bool
FixRoute
(
);
bool
FixRoute
(
);
/**
* Function CurrentNode()
...
...
@@ -86,7 +83,6 @@ public:
* Returns the most recent world state, including all
* items changed due to dragging operation.
*/
PNS_NODE
*
CurrentNode
()
const
;
/**
...
...
@@ -97,11 +93,10 @@ public:
const
PNS_ITEMSET
Traces
();
/// @copydoc PNS_ALGO_BASE::Logger()
virtual
PNS_LOGGER
*
Logger
();
virtual
PNS_LOGGER
*
Logger
();
private
:
typedef
std
::
pair
<
PNS_LINE
*
,
PNS_LINE
*>
LinePair
;
typedef
std
::
pair
<
PNS_LINE
*
,
PNS_LINE
*>
LinePair
;
typedef
std
::
vector
<
LinePair
>
LinePairVec
;
enum
DragMode
{
...
...
@@ -110,25 +105,25 @@ private:
VIA
};
bool
dragMarkObstacles
(
const
VECTOR2I
&
aP
);
bool
dragShove
(
const
VECTOR2I
&
aP
);
bool
startDragSegment
(
const
VECTOR2D
&
aP
,
PNS_SEGMENT
*
aSeg
);
bool
startDragVia
(
const
VECTOR2D
&
aP
,
PNS_VIA
*
aVia
);
void
dumbDragVia
(
PNS_VIA
*
aVia
,
PNS_NODE
*
aNode
,
const
VECTOR2I
&
aP
);
bool
dragMarkObstacles
(
const
VECTOR2I
&
aP
);
bool
dragShove
(
const
VECTOR2I
&
aP
);
bool
startDragSegment
(
const
VECTOR2D
&
aP
,
PNS_SEGMENT
*
aSeg
);
bool
startDragVia
(
const
VECTOR2D
&
aP
,
PNS_VIA
*
aVia
);
void
dumbDragVia
(
PNS_VIA
*
aVia
,
PNS_NODE
*
aNode
,
const
VECTOR2I
&
aP
);
PNS_NODE
*
m_world
;
PNS_NODE
*
m_lastNode
;
PNS_NODE
*
m_world
;
PNS_NODE
*
m_lastNode
;
DragMode
m_mode
;
PNS_LINE
*
m_draggedLine
;
PNS_VIA
*
m_draggedVia
;
PNS_LINE
*
m_draggedLine
;
PNS_VIA
*
m_draggedVia
;
PNS_LINE
m_lastValidDraggedLine
;
PNS_SHOVE
*
m_shove
;
PNS_SHOVE
*
m_shove
;
int
m_draggedSegmentIndex
;
bool
m_dragStatus
;
PNS_MODE
m_currentMode
;
std
::
vector
<
PNS_LINE
>
m_origViaConnections
;
std
::
vector
<
PNS_LINE
>
m_draggedViaConnections
;
PNS_VIA
*
m_initialVia
;
PNS_VIA
*
m_initialVia
;
PNS_ITEMSET
m_draggedItems
;
};
...
...
pcbnew/router/pns_index.h
View file @
ad1b138f
...
...
@@ -39,13 +39,12 @@
* are assigned to separate R-Tree subindices depending on their type and spanned layers, reducing
* overlap and improving search time.
**/
class
PNS_INDEX
{
public
:
typedef
std
::
list
<
PNS_ITEM
*>
N
etItemsList
;
typedef
SHAPE_INDEX
<
PNS_ITEM
*>
I
temShapeIndex
;
typedef
boost
::
unordered_set
<
PNS_ITEM
*>
I
temSet
;
typedef
std
::
list
<
PNS_ITEM
*>
N
ET_ITEMS_LIST
;
typedef
SHAPE_INDEX
<
PNS_ITEM
*>
I
TEM_SHAPE_INDEX
;
typedef
boost
::
unordered_set
<
PNS_ITEM
*>
I
TEM_SET
;
PNS_INDEX
();
~
PNS_INDEX
();
...
...
@@ -115,7 +114,7 @@ public:
*
* Returns list of all items in a given net.
*/
N
etItemsList
*
GetItemsForNet
(
int
aNet
);
N
ET_ITEMS_LIST
*
GetItemsForNet
(
int
aNet
);
/**
* Function Contains()
...
...
@@ -134,8 +133,8 @@ public:
*/
int
Size
()
const
{
return
m_allItems
.
size
();
}
I
temSet
::
iterator
begin
()
{
return
m_allItems
.
begin
();
}
I
temSet
::
iterator
end
()
{
return
m_allItems
.
end
();
}
I
TEM_SET
::
iterator
begin
()
{
return
m_allItems
.
begin
();
}
I
TEM_SET
::
iterator
end
()
{
return
m_allItems
.
end
();
}
private
:
static
const
int
MaxSubIndices
=
64
;
...
...
@@ -149,21 +148,20 @@ private:
template
<
class
Visitor
>
int
querySingle
(
int
index
,
const
SHAPE
*
aShape
,
int
aMinDistance
,
Visitor
&
aVisitor
);
I
temShapeIndex
*
getSubindex
(
const
PNS_ITEM
*
aItem
);
I
TEM_SHAPE_INDEX
*
getSubindex
(
const
PNS_ITEM
*
aItem
);
I
temShapeIndex
*
m_subIndices
[
MaxSubIndices
];
std
::
map
<
int
,
N
etItemsList
>
m_netMap
;
I
temSet
m_allItems
;
I
TEM_SHAPE_INDEX
*
m_subIndices
[
MaxSubIndices
];
std
::
map
<
int
,
N
ET_ITEMS_LIST
>
m_netMap
;
I
TEM_SET
m_allItems
;
};
PNS_INDEX
::
PNS_INDEX
()
{
memset
(
m_subIndices
,
0
,
sizeof
(
m_subIndices
)
);
}
PNS_INDEX
::
I
temShapeIndex
*
PNS_INDEX
::
getSubindex
(
const
PNS_ITEM
*
aItem
)
PNS_INDEX
::
I
TEM_SHAPE_INDEX
*
PNS_INDEX
::
getSubindex
(
const
PNS_ITEM
*
aItem
)
{
int
idx_n
=
-
1
;
...
...
@@ -199,7 +197,7 @@ PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
assert
(
idx_n
>=
0
&&
idx_n
<
MaxSubIndices
);
if
(
!
m_subIndices
[
idx_n
]
)
m_subIndices
[
idx_n
]
=
new
I
temShapeIndex
;
m_subIndices
[
idx_n
]
=
new
I
TEM_SHAPE_INDEX
;
return
m_subIndices
[
idx_n
];
}
...
...
@@ -207,9 +205,7 @@ PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
void
PNS_INDEX
::
Add
(
PNS_ITEM
*
aItem
)
{
ItemShapeIndex
*
idx
=
getSubindex
(
aItem
);
ITEM_SHAPE_INDEX
*
idx
=
getSubindex
(
aItem
);
idx
->
Add
(
aItem
);
m_allItems
.
insert
(
aItem
);
...
...
@@ -224,7 +220,7 @@ void PNS_INDEX::Add( PNS_ITEM* aItem )
void
PNS_INDEX
::
Remove
(
PNS_ITEM
*
aItem
)
{
I
temShapeIndex
*
idx
=
getSubindex
(
aItem
);
I
TEM_SHAPE_INDEX
*
idx
=
getSubindex
(
aItem
);
idx
->
Remove
(
aItem
);
m_allItems
.
erase
(
aItem
);
...
...
@@ -303,7 +299,7 @@ void PNS_INDEX::Clear()
{
for
(
int
i
=
0
;
i
<
MaxSubIndices
;
++
i
)
{
I
temShapeIndex
*
idx
=
m_subIndices
[
i
];
I
TEM_SHAPE_INDEX
*
idx
=
m_subIndices
[
i
];
if
(
idx
)
delete
idx
;
...
...
@@ -319,7 +315,7 @@ PNS_INDEX::~PNS_INDEX()
}
PNS_INDEX
::
N
etItemsList
*
PNS_INDEX
::
GetItemsForNet
(
int
aNet
)
PNS_INDEX
::
N
ET_ITEMS_LIST
*
PNS_INDEX
::
GetItemsForNet
(
int
aNet
)
{
if
(
m_netMap
.
find
(
aNet
)
==
m_netMap
.
end
()
)
return
NULL
;
...
...
pcbnew/router/pns_item.cpp
View file @
ad1b138f
...
...
@@ -50,8 +50,7 @@ bool PNS_ITEM::Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
const
PNS_LINE
*
line
=
static_cast
<
const
PNS_LINE
*>
(
aOther
);
if
(
line
->
EndsWithVia
()
)
return
collideSimple
(
&
line
->
Via
(),
aClearance
-
line
->
Width
()
/
2
,
aNeedMTV
,
aMTV
);
return
collideSimple
(
&
line
->
Via
(),
aClearance
-
line
->
Width
()
/
2
,
aNeedMTV
,
aMTV
);
}
return
false
;
...
...
@@ -85,5 +84,4 @@ const std::string PNS_ITEM::KindStr() const
PNS_ITEM
::~
PNS_ITEM
()
{
}
pcbnew/router/pns_item.h
View file @
ad1b138f
...
...
@@ -91,7 +91,7 @@ public:
*
* Returns a deep copy of the item
*/
virtual
PNS_ITEM
*
Clone
(
)
const
=
0
;
virtual
PNS_ITEM
*
Clone
()
const
=
0
;
/*
* Function Hull()
...
...
@@ -104,7 +104,7 @@ public:
virtual
const
SHAPE_LINE_CHAIN
Hull
(
int
aClearance
=
0
,
int
aWalkaroundThickness
=
0
)
const
{
return
SHAPE_LINE_CHAIN
();
}
;
}
/**
* Function Kind()
...
...
@@ -123,7 +123,7 @@ public:
*/
bool
OfKind
(
int
aKindMask
)
const
{
return
(
aKindMask
&
m_kind
)
!=
0
;
return
(
aKindMask
&
m_kind
)
!=
0
;
}
/**
...
...
@@ -219,7 +219,7 @@ public:
* Returns true if the set of layers spanned by aOther overlaps our
* layers.
*/
bool
LayersOverlap
(
const
PNS_ITEM
*
aOther
)
const
bool
LayersOverlap
(
const
PNS_ITEM
*
aOther
)
const
{
return
Layers
().
Overlaps
(
aOther
->
Layers
()
);
}
...
...
@@ -252,7 +252,6 @@ public:
*/
PNS_NODE
*
Owner
()
const
{
return
m_owner
;
}
/**
* Function Collide()
*
...
...
@@ -308,7 +307,7 @@ public:
return
m_marker
;
}
virtual
void
SetRank
(
int
aRank
)
virtual
void
SetRank
(
int
aRank
)
{
m_rank
=
aRank
;
}
...
...
@@ -318,10 +317,10 @@ public:
return
m_rank
;
}
virtual
VECTOR2I
Anchor
(
int
n
)
const
virtual
VECTOR2I
Anchor
(
int
n
)
const
{
return
VECTOR2I
();
}
;
}
virtual
int
AnchorCount
()
const
{
...
...
@@ -329,15 +328,14 @@ public:
}
private
:
bool
collideSimple
(
const
PNS_ITEM
*
aOther
,
int
aClearance
,
bool
aNeedMTV
,
VECTOR2I
&
aMTV
)
const
;
protected
:
PnsKind
m_kind
;
BOARD_CONNECTED_ITEM
*
m_parent
;
PNS_NODE
*
m_owner
;
BOARD_CONNECTED_ITEM
*
m_parent
;
PNS_NODE
*
m_owner
;
PNS_LAYERSET
m_layers
;
bool
m_movable
;
...
...
pcbnew/router/pns_itemset.cpp
View file @
ad1b138f
...
...
@@ -22,8 +22,7 @@
#include "pns_itemset.h"
PNS_ITEMSET
::
PNS_ITEMSET
(
PNS_ITEM
*
aInitialItem
)
PNS_ITEMSET
::
PNS_ITEMSET
(
PNS_ITEM
*
aInitialItem
)
{
if
(
aInitialItem
)
m_items
.
push_back
(
aInitialItem
);
...
...
@@ -38,7 +37,7 @@ PNS_ITEMSET::~PNS_ITEMSET()
void
PNS_ITEMSET
::
Clear
()
{
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_ownedItems
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_ownedItems
)
{
delete
item
;
}
...
...
@@ -47,9 +46,10 @@ void PNS_ITEMSET::Clear()
m_ownedItems
.
clear
();
}
PNS_ITEMSET
&
PNS_ITEMSET
::
FilterLayers
(
int
aStart
,
int
aEnd
)
{
I
temVector
newItems
;
I
TEM_VECTOR
newItems
;
PNS_LAYERSET
l
;
if
(
aEnd
<
0
)
...
...
@@ -57,39 +57,44 @@ PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd )
else
l
=
PNS_LAYERSET
(
aStart
,
aEnd
);
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_items
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_items
)
if
(
item
->
Layers
().
Overlaps
(
l
)
)
newItems
.
push_back
(
item
);
m_items
=
newItems
;
return
*
this
;
}
PNS_ITEMSET
&
PNS_ITEMSET
::
FilterKinds
(
int
aKindMask
)
{
ItemVector
newItems
;
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_items
)
ITEM_VECTOR
newItems
;
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_items
)
{
if
(
item
->
OfKind
(
aKindMask
)
)
newItems
.
push_back
(
item
);
}
m_items
=
newItems
;
return
*
this
;
}
PNS_ITEMSET
&
PNS_ITEMSET
::
FilterNet
(
int
aNet
)
{
ItemVector
newItems
;
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_items
)
ITEM_VECTOR
newItems
;
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_items
)
{
if
(
item
->
Net
()
==
aNet
)
newItems
.
push_back
(
item
);
}
m_items
=
newItems
;
return
*
this
;
}
pcbnew/router/pns_itemset.h
View file @
ad1b138f
...
...
@@ -35,27 +35,28 @@
class
PNS_ITEMSET
{
public
:
typedef
std
::
vector
<
PNS_ITEM
*>
I
temVector
;
typedef
std
::
vector
<
PNS_ITEM
*>
I
TEM_VECTOR
;
PNS_ITEMSET
(
PNS_ITEM
*
aInitialItem
=
NULL
);
PNS_ITEMSET
(
PNS_ITEM
*
aInitialItem
=
NULL
);
PNS_ITEMSET
(
const
PNS_ITEMSET
&
aOther
)
PNS_ITEMSET
(
const
PNS_ITEMSET
&
aOther
)
{
m_items
=
aOther
.
m_items
;
m_ownedItems
=
I
temVector
();
m_ownedItems
=
I
TEM_VECTOR
();
}
const
PNS_ITEMSET
&
operator
=
(
const
PNS_ITEMSET
&
aOther
)
const
PNS_ITEMSET
&
operator
=
(
const
PNS_ITEMSET
&
aOther
)
{
m_items
=
aOther
.
m_items
;
m_ownedItems
=
ItemVector
();
m_ownedItems
=
ITEM_VECTOR
();
return
*
this
;
}
~
PNS_ITEMSET
();
I
temVector
&
Items
()
{
return
m_items
;
}
const
I
temVector
&
CItems
()
const
{
return
m_items
;
}
I
TEM_VECTOR
&
Items
()
{
return
m_items
;
}
const
I
TEM_VECTOR
&
CItems
()
const
{
return
m_items
;
}
PNS_ITEMSET
&
FilterLayers
(
int
aStart
,
int
aEnd
=
-
1
);
PNS_ITEMSET
&
FilterKinds
(
int
aKindMask
);
...
...
@@ -63,24 +64,24 @@ public:
int
Size
()
{
return
m_items
.
size
();
}
void
Add
(
PNS_ITEM
*
i
tem
)
void
Add
(
PNS_ITEM
*
aI
tem
)
{
m_items
.
push_back
(
i
tem
);
m_items
.
push_back
(
aI
tem
);
}
PNS_ITEM
*
Get
(
int
index
)
const
{
return
m_items
[
index
];
}
void
Clear
();
void
AddOwned
(
PNS_ITEM
*
aItem
)
void
AddOwned
(
PNS_ITEM
*
aItem
)
{
m_items
.
push_back
(
aItem
);
m_ownedItems
.
push_back
(
aItem
);
}
private
:
I
temVector
m_items
;
I
temVector
m_ownedItems
;
I
TEM_VECTOR
m_items
;
I
TEM_VECTOR
m_ownedItems
;
};
#endif
pcbnew/router/pns_joint.h
View file @
ad1b138f
...
...
@@ -40,11 +40,11 @@
class
PNS_JOINT
:
public
PNS_ITEM
{
public
:
typedef
std
::
vector
<
PNS_ITEM
*>
L
inkedItems
;
typedef
std
::
vector
<
PNS_ITEM
*>
L
INKED_ITEMS
;
///> Joints are hashed by their position, layers and net.
/// Linked items are, obviously, not hashed
struct
H
ashTag
struct
H
ASH_TAG
{
VECTOR2I
pos
;
int
net
;
...
...
@@ -53,8 +53,7 @@ public:
PNS_JOINT
()
:
PNS_ITEM
(
JOINT
)
{}
PNS_JOINT
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
=
-
1
)
:
PNS_JOINT
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
=
-
1
)
:
PNS_ITEM
(
JOINT
)
{
m_tag
.
pos
=
aPos
;
...
...
@@ -62,14 +61,14 @@ public:
m_layers
=
aLayers
;
}
PNS_JOINT
(
const
PNS_JOINT
&
b
)
:
PNS_JOINT
(
const
PNS_JOINT
&
aB
)
:
PNS_ITEM
(
JOINT
)
{
m_layers
=
b
.
m_layers
;
m_tag
.
pos
=
b
.
m_tag
.
pos
;
m_tag
.
net
=
b
.
m_tag
.
net
;
m_linkedItems
=
b
.
m_linkedItems
;
m_layers
=
b
.
m_layers
;
m_layers
=
aB
.
m_layers
;
m_tag
.
pos
=
aB
.
m_tag
.
pos
;
m_tag
.
net
=
aB
.
m_tag
.
net
;
m_linkedItems
=
aB
.
m_linkedItems
;
m_layers
=
aB
.
m_layers
;
}
PNS_ITEM
*
Clone
(
)
const
...
...
@@ -85,8 +84,7 @@ public:
if
(
m_linkedItems
.
size
()
!=
2
)
return
false
;
if
(
m_linkedItems
[
0
]
->
Kind
()
!=
SEGMENT
||
m_linkedItems
[
1
]
->
Kind
()
!=
SEGMENT
)
if
(
m_linkedItems
[
0
]
->
Kind
()
!=
SEGMENT
||
m_linkedItems
[
1
]
->
Kind
()
!=
SEGMENT
)
return
false
;
PNS_SEGMENT
*
seg1
=
static_cast
<
PNS_SEGMENT
*>
(
m_linkedItems
[
0
]
);
...
...
@@ -99,8 +97,7 @@ public:
///> Links the joint to a given board item (when it's added to the PNS_NODE)
void
Link
(
PNS_ITEM
*
aItem
)
{
LinkedItems
::
iterator
f
=
std
::
find
(
m_linkedItems
.
begin
(),
m_linkedItems
.
end
(),
aItem
);
LINKED_ITEMS
::
iterator
f
=
std
::
find
(
m_linkedItems
.
begin
(),
m_linkedItems
.
end
(),
aItem
);
if
(
f
!=
m_linkedItems
.
end
()
)
return
;
...
...
@@ -112,8 +109,7 @@ public:
///> Returns true if the joint became dangling after unlinking.
bool
Unlink
(
PNS_ITEM
*
aItem
)
{
LinkedItems
::
iterator
f
=
std
::
find
(
m_linkedItems
.
begin
(),
m_linkedItems
.
end
(),
aItem
);
LINKED_ITEMS
::
iterator
f
=
std
::
find
(
m_linkedItems
.
begin
(),
m_linkedItems
.
end
(),
aItem
);
if
(
f
!=
m_linkedItems
.
end
()
)
m_linkedItems
.
erase
(
f
);
...
...
@@ -131,17 +127,19 @@ public:
return
static_cast
<
PNS_SEGMENT
*>
(
m_linkedItems
[
m_linkedItems
[
0
]
==
aCurrent
?
1
:
0
]
);
}
PNS_VIA
*
Via
()
PNS_VIA
*
Via
()
{
for
(
LINKED_ITEMS
::
iterator
i
=
m_linkedItems
.
begin
();
i
!=
m_linkedItems
.
end
();
++
i
)
{
for
(
LinkedItems
::
iterator
i
=
m_linkedItems
.
begin
();
i
!=
m_linkedItems
.
end
();
++
i
)
if
(
(
*
i
)
->
Kind
()
==
PNS_ITEM
::
VIA
)
return
(
PNS_VIA
*
)(
*
i
);
return
(
PNS_VIA
*
)(
*
i
);
}
return
NULL
;
}
/// trivial accessors
const
H
ashTag
&
Tag
()
const
const
H
ASH_TAG
&
Tag
()
const
{
return
m_tag
;
}
...
...
@@ -156,7 +154,7 @@ public:
return
m_tag
.
net
;
}
L
inkedItems
&
LinkList
()
L
INKED_ITEMS
&
LinkList
()
{
return
m_linkedItems
;
}
...
...
@@ -166,10 +164,12 @@ public:
{
int
n
=
0
;
for
(
L
inkedItems
::
const_iterator
i
=
m_linkedItems
.
begin
();
for
(
L
INKED_ITEMS
::
const_iterator
i
=
m_linkedItems
.
begin
();
i
!=
m_linkedItems
.
end
();
++
i
)
{
if
(
(
*
i
)
->
Kind
()
&
aMask
)
n
++
;
}
return
n
;
}
...
...
@@ -189,10 +189,12 @@ public:
m_layers
.
Merge
(
aJoint
.
m_layers
);
// fixme: duplicate links (?)
for
(
L
inkedItems
::
const_iterator
i
=
aJoint
.
m_linkedItems
.
begin
();
for
(
L
INKED_ITEMS
::
const_iterator
i
=
aJoint
.
m_linkedItems
.
begin
();
i
!=
aJoint
.
m_linkedItems
.
end
();
++
i
)
{
m_linkedItems
.
push_back
(
*
i
);
}
}
bool
Overlaps
(
const
PNS_JOINT
&
rhs
)
const
{
...
...
@@ -202,27 +204,27 @@ public:
private
:
///> hash tag for unordered_multimap
H
ashTag
m_tag
;
H
ASH_TAG
m_tag
;
///> list of items linked to this joint
L
inkedItems
m_linkedItems
;
L
INKED_ITEMS
m_linkedItems
;
};
// hash function & comparison operator for boost::unordered_map<>
inline
bool
operator
==
(
PNS_JOINT
::
H
ashTag
const
&
p
1
,
PNS_JOINT
::
H
ashTag
const
&
p
2
)
inline
bool
operator
==
(
PNS_JOINT
::
H
ASH_TAG
const
&
aP
1
,
PNS_JOINT
::
H
ASH_TAG
const
&
aP
2
)
{
return
p1
.
pos
==
p2
.
pos
&&
p1
.
net
==
p
2
.
net
;
return
aP1
.
pos
==
aP2
.
pos
&&
aP1
.
net
==
aP
2
.
net
;
}
inline
std
::
size_t
hash_value
(
PNS_JOINT
::
H
ashTag
const
&
p
)
inline
std
::
size_t
hash_value
(
PNS_JOINT
::
H
ASH_TAG
const
&
aP
)
{
std
::
size_t
seed
=
0
;
boost
::
hash_combine
(
seed
,
p
.
pos
.
x
);
boost
::
hash_combine
(
seed
,
p
.
pos
.
y
);
boost
::
hash_combine
(
seed
,
p
.
net
);
boost
::
hash_combine
(
seed
,
aP
.
pos
.
x
);
boost
::
hash_combine
(
seed
,
aP
.
pos
.
y
);
boost
::
hash_combine
(
seed
,
aP
.
net
);
return
seed
;
}
...
...
pcbnew/router/pns_layerset.h
View file @
ad1b138f
...
...
@@ -50,17 +50,17 @@ public:
m_start
=
m_end
=
aLayer
;
}
PNS_LAYERSET
(
const
PNS_LAYERSET
&
b
)
:
m_start
(
b
.
m_start
),
m_end
(
b
.
m_end
)
PNS_LAYERSET
(
const
PNS_LAYERSET
&
aB
)
:
m_start
(
aB
.
m_start
),
m_end
(
aB
.
m_end
)
{}
~
PNS_LAYERSET
()
{};
const
PNS_LAYERSET
&
operator
=
(
const
PNS_LAYERSET
&
b
)
const
PNS_LAYERSET
&
operator
=
(
const
PNS_LAYERSET
&
aB
)
{
m_start
=
b
.
m_start
;
m_end
=
b
.
m_end
;
m_start
=
aB
.
m_start
;
m_end
=
aB
.
m_end
;
return
*
this
;
}
...
...
pcbnew/router/pns_line.cpp
View file @
ad1b138f
...
...
@@ -50,14 +50,15 @@ PNS_LINE::PNS_LINE( const PNS_LINE& aOther ) :
copyLinks
(
&
aOther
);
}
PNS_LINE
::~
PNS_LINE
()
{
if
(
m_segmentRefs
)
delete
m_segmentRefs
;
}
;
}
const
PNS_LINE
&
PNS_LINE
::
operator
=
(
const
PNS_LINE
&
aOther
)
const
PNS_LINE
&
PNS_LINE
::
operator
=
(
const
PNS_LINE
&
aOther
)
{
m_line
=
aOther
.
m_line
;
m_width
=
aOther
.
m_width
;
...
...
@@ -75,53 +76,62 @@ const PNS_LINE& PNS_LINE :: operator= (const PNS_LINE& aOther)
return
*
this
;
}
PNS_LINE
*
PNS_LINE
::
Clone
(
)
const
PNS_LINE
*
PNS_LINE
::
Clone
()
const
{
PNS_LINE
*
l
=
new
PNS_LINE
(
*
this
);
return
l
;
}
void
PNS_LINE
::
Mark
(
int
aMarker
)
void
PNS_LINE
::
Mark
(
int
aMarker
)
{
m_marker
=
aMarker
;
if
(
m_segmentRefs
)
if
(
m_segmentRefs
)
{
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
m_segmentRefs
)
s
->
Mark
(
aMarker
);
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
m_segmentRefs
)
s
->
Mark
(
aMarker
);
}
}
void
PNS_LINE
::
Unmark
()
{
if
(
m_segmentRefs
)
if
(
m_segmentRefs
)
{
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
m_segmentRefs
)
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
m_segmentRefs
)
s
->
Unmark
();
}
m_marker
=
0
;
}
int
PNS_LINE
::
Marker
()
const
{
int
marker
=
m_marker
;
if
(
m_segmentRefs
)
if
(
m_segmentRefs
)
{
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
m_segmentRefs
)
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
m_segmentRefs
)
marker
|=
s
->
Marker
();
}
return
marker
;
}
void
PNS_LINE
::
copyLinks
(
const
PNS_LINE
*
aParent
)
{
if
(
aParent
->
m_segmentRefs
==
NULL
)
if
(
aParent
->
m_segmentRefs
==
NULL
)
{
m_segmentRefs
=
NULL
;
return
;
}
m_segmentRefs
=
new
S
egmentRefs
();
m_segmentRefs
=
new
S
EGMENT_REFS
();
*
m_segmentRefs
=
*
aParent
->
m_segmentRefs
;
}
...
...
@@ -140,6 +150,7 @@ PNS_SEGMENT* PNS_SEGMENT::Clone( ) const
return
s
;
}
int
PNS_LINE
::
CountCorners
(
int
aAngles
)
{
int
count
=
0
;
...
...
@@ -161,6 +172,7 @@ int PNS_LINE::CountCorners( int aAngles )
return
count
;
}
bool
PNS_LINE
::
Walkaround
(
SHAPE_LINE_CHAIN
aObstacle
,
SHAPE_LINE_CHAIN
&
aPre
,
SHAPE_LINE_CHAIN
&
aWalk
,
SHAPE_LINE_CHAIN
&
aPost
,
bool
aCw
)
const
{
...
...
@@ -171,38 +183,37 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
if
(
line
.
SegmentCount
()
<
1
)
return
false
;
if
(
aObstacle
.
PointInside
(
line
.
CPoint
(
0
)
)
||
aObstacle
.
PointInside
(
line
.
CPoint
(
-
1
)
)
)
if
(
aObstacle
.
PointInside
(
line
.
CPoint
(
0
)
)
||
aObstacle
.
PointInside
(
line
.
CPoint
(
-
1
)
)
)
return
false
;
SHAPE_LINE_CHAIN
::
INTERSECTIONS
ips
,
ips2
;
line
.
Intersect
(
aObstacle
,
ips
);
line
.
Intersect
(
aObstacle
,
ips
);
int
nearest_dist
=
INT_MAX
;
int
farthest_dist
=
0
;
SHAPE_LINE_CHAIN
::
INTERSECTION
nearest
,
farthest
;
for
(
int
i
=
0
;
i
<
(
int
)
ips
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
ips
.
size
();
i
++
)
{
const
VECTOR2I
p
=
ips
[
i
].
p
;
int
dist
=
line
.
PathLength
(
p
);
int
dist
=
line
.
PathLength
(
p
);
if
(
dist
<=
nearest_dist
)
if
(
dist
<=
nearest_dist
)
{
nearest_dist
=
dist
;
nearest
=
ips
[
i
];
}
if
(
dist
>=
farthest_dist
)
if
(
dist
>=
farthest_dist
)
{
farthest_dist
=
dist
;
farthest
=
ips
[
i
];
}
}
if
(
ips
.
size
()
<=
1
||
nearest
.
p
==
farthest
.
p
)
if
(
ips
.
size
()
<=
1
||
nearest
.
p
==
farthest
.
p
)
{
aPre
=
line
;
return
true
;
...
...
@@ -213,13 +224,13 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
aPre
.
Simplify
();
aWalk
.
Clear
();
aWalk
.
SetClosed
(
false
);
aWalk
.
SetClosed
(
false
);
aWalk
.
Append
(
nearest
.
p
);
int
i
=
nearest
.
their
.
Index
();
assert
(
nearest
.
their
.
Index
()
>=
0
);
assert
(
farthest
.
their
.
Index
()
>=
0
);
assert
(
nearest
.
their
.
Index
()
>=
0
);
assert
(
farthest
.
their
.
Index
()
>=
0
);
assert
(
nearest_dist
<=
farthest_dist
);
...
...
@@ -231,14 +242,14 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
i
=
i_first
;
while
(
i
!=
i_last
)
while
(
i
!=
i_last
)
{
aWalk
.
Append
(
aObstacle
.
CPoint
(
i
)
);
i
+=
(
aCw
?
1
:
-
1
);
aWalk
.
Append
(
aObstacle
.
CPoint
(
i
)
);
i
+=
(
aCw
?
1
:
-
1
);
if
(
i
<
0
)
if
(
i
<
0
)
i
=
aObstacle
.
PointCount
()
-
1
;
else
if
(
i
==
aObstacle
.
PointCount
()
)
else
if
(
i
==
aObstacle
.
PointCount
()
)
i
=
0
;
}
...
...
@@ -249,9 +260,11 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
aPost
.
Append
(
farthest
.
p
);
aPost
.
Append
(
line
.
Slice
(
farthest
.
our
.
Index
()
+
1
,
-
1
)
);
aPost
.
Simplify
();
return
true
;
}
void
PNS_LINE
::
Walkaround
(
const
SHAPE_LINE_CHAIN
&
aObstacle
,
SHAPE_LINE_CHAIN
&
aPath
,
bool
aCw
)
const
...
...
@@ -298,12 +311,12 @@ const PNS_LINE PNS_LINE::ClipToNearestObstacle( PNS_NODE* aNode ) const
{
PNS_LINE
l
(
*
this
);
PNS_NODE
::
O
ptObstacle
obs
=
aNode
->
NearestObstacle
(
&
l
);
PNS_NODE
::
O
PT_OBSTACLE
obs
=
aNode
->
NearestObstacle
(
&
l
);
if
(
obs
)
{
l
.
RemoveVia
();
int
p
=
l
.
Line
().
Split
(
obs
->
ip_f
irst
);
int
p
=
l
.
Line
().
Split
(
obs
->
m_ipF
irst
);
l
.
Line
().
Remove
(
p
+
1
,
-
1
);
}
...
...
@@ -325,113 +338,121 @@ void PNS_LINE::ShowLinks()
printf
(
"seg %d: %p
\n
"
,
i
,
(
*
m_segmentRefs
)[
i
]
);
}
SHAPE_LINE_CHAIN
dragCornerInternal
(
const
SHAPE_LINE_CHAIN
&
o
rigin
,
const
VECTOR2I
&
aP
)
SHAPE_LINE_CHAIN
dragCornerInternal
(
const
SHAPE_LINE_CHAIN
&
aO
rigin
,
const
VECTOR2I
&
aP
)
{
optional
<
SHAPE_LINE_CHAIN
>
picked
;
int
i
;
int
d
=
2
;
if
(
origin
.
CSegment
(
-
1
).
Length
()
>
100000
*
30
)
// fixme: constant/parameter?
if
(
aOrigin
.
CSegment
(
-
1
).
Length
()
>
100000
*
30
)
// fixme: constant/parameter?
d
=
1
;
for
(
i
=
origin
.
SegmentCount
()
-
d
;
i
>=
0
;
i
--
)
for
(
i
=
aOrigin
.
SegmentCount
()
-
d
;
i
>=
0
;
i
--
)
{
DIRECTION_45
d_start
(
origin
.
CSegment
(
i
));
VECTOR2I
p_start
=
origin
.
CPoint
(
i
);
SHAPE_LINE_CHAIN
paths
[
2
];
DIRECTION_45
d_start
(
aOrigin
.
CSegment
(
i
)
);
VECTOR2I
p_start
=
aOrigin
.
CPoint
(
i
);
SHAPE_LINE_CHAIN
paths
[
2
];
DIRECTION_45
dirs
[
2
];
DIRECTION_45
d_prev
=
(
i
>
0
?
DIRECTION_45
(
origin
.
CSegment
(
i
-
1
))
:
DIRECTION_45
()
);
DIRECTION_45
d_prev
=
(
i
>
0
?
DIRECTION_45
(
aOrigin
.
CSegment
(
i
-
1
)
)
:
DIRECTION_45
()
);
for
(
int
j
=
0
;
j
<
2
;
j
++
)
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
paths
[
j
]
=
d_start
.
BuildInitialTrace
(
p_start
,
aP
,
j
);
dirs
[
j
]
=
DIRECTION_45
(
paths
[
j
].
CSegment
(
0
)
);
paths
[
j
]
=
d_start
.
BuildInitialTrace
(
p_start
,
aP
,
j
);
dirs
[
j
]
=
DIRECTION_45
(
paths
[
j
].
CSegment
(
0
)
);
}
for
(
int
j
=
0
;
j
<
2
;
j
++
)
if
(
dirs
[
j
]
==
d_start
)
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
if
(
dirs
[
j
]
==
d_start
)
{
picked
=
paths
[
j
];
break
;
}
}
if
(
picked
)
if
(
picked
)
break
;
for
(
int
j
=
0
;
j
<
2
;
j
++
)
if
(
dirs
[
j
].
IsObtuse
(
d_prev
))
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
if
(
dirs
[
j
].
IsObtuse
(
d_prev
)
)
{
picked
=
paths
[
j
];
break
;
}
if
(
picked
)
}
if
(
picked
)
break
;
}
if
(
picked
)
if
(
picked
)
{
SHAPE_LINE_CHAIN
path
=
origin
.
Slice
(
0
,
i
);
path
.
Append
(
*
picked
);
return
path
;
SHAPE_LINE_CHAIN
path
=
aOrigin
.
Slice
(
0
,
i
);
path
.
Append
(
*
picked
);
return
path
;
}
return
DIRECTION_45
().
BuildInitialTrace
(
origin
.
CPoint
(
0
),
aP
,
true
);
return
DIRECTION_45
().
BuildInitialTrace
(
aOrigin
.
CPoint
(
0
),
aP
,
true
);
}
void
PNS_LINE
::
DragCorner
(
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aSnappingThreshold
)
{
SHAPE_LINE_CHAIN
path
;
VECTOR2I
snapped
=
snapDraggedCorner
(
m_line
,
aP
,
aIndex
,
aSnappingThreshold
);
if
(
aIndex
==
0
)
if
(
aIndex
==
0
)
path
=
dragCornerInternal
(
m_line
.
Reverse
(),
snapped
).
Reverse
();
else
if
(
aIndex
==
m_line
.
SegmentCount
()
)
path
=
dragCornerInternal
(
m_line
,
snapped
);
else
{
else
{
// fixme: awkward behaviour for "outwards" drags
path
=
dragCornerInternal
(
m_line
.
Slice
(
0
,
aIndex
),
snapped
);
SHAPE_LINE_CHAIN
path_rev
=
dragCornerInternal
(
m_line
.
Slice
(
aIndex
,
-
1
).
Reverse
(),
snapped
).
Reverse
();
path
.
Append
(
path_rev
);
path
=
dragCornerInternal
(
m_line
.
Slice
(
0
,
aIndex
),
snapped
);
SHAPE_LINE_CHAIN
path_rev
=
dragCornerInternal
(
m_line
.
Slice
(
aIndex
,
-
1
).
Reverse
(),
snapped
).
Reverse
();
path
.
Append
(
path_rev
);
}
path
.
Simplify
();
m_line
=
path
;
}
VECTOR2I
PNS_LINE
::
snapDraggedCorner
(
const
SHAPE_LINE_CHAIN
&
aPath
,
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aThreshold
)
const
VECTOR2I
PNS_LINE
::
snapDraggedCorner
(
const
SHAPE_LINE_CHAIN
&
aPath
,
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aThreshold
)
const
{
int
s_start
=
std
::
max
(
aIndex
-
2
,
0
);
int
s_end
=
std
::
min
(
aIndex
+
2
,
aPath
.
SegmentCount
()
-
1
);
int
s_start
=
std
::
max
(
aIndex
-
2
,
0
);
int
s_end
=
std
::
min
(
aIndex
+
2
,
aPath
.
SegmentCount
()
-
1
);
int
i
,
j
;
int
best_dist
=
INT_MAX
;
VECTOR2I
best_snap
=
aP
;
if
(
aThreshold
<=
0
)
if
(
aThreshold
<=
0
)
return
aP
;
for
(
i
=
s_start
;
i
<=
s_end
;
i
++
)
for
(
i
=
s_start
;
i
<=
s_end
;
i
++
)
{
const
SEG
&
a
=
aPath
.
CSegment
(
i
);
const
SEG
&
a
=
aPath
.
CSegment
(
i
);
for
(
j
=
s_start
;
j
<
i
;
j
++
)
for
(
j
=
s_start
;
j
<
i
;
j
++
)
{
const
SEG
&
b
=
aPath
.
CSegment
(
j
);
const
SEG
&
b
=
aPath
.
CSegment
(
j
);
if
(
!
(
DIRECTION_45
(
a
).
IsObtuse
(
DIRECTION_45
(
b
))
)
)
if
(
!
(
DIRECTION_45
(
a
).
IsObtuse
(
DIRECTION_45
(
b
)
)
)
)
continue
;
OPT_VECTOR2I
ip
=
a
.
IntersectLines
(
b
);
if
(
ip
)
if
(
ip
)
{
int
dist
=
(
*
ip
-
aP
).
EuclideanNorm
();
int
dist
=
(
*
ip
-
aP
).
EuclideanNorm
();
if
(
dist
<
aThreshold
&&
dist
<
best_dist
)
{
best_dist
=
dist
;
...
...
@@ -444,40 +465,47 @@ VECTOR2I PNS_LINE::snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTO
return
best_snap
;
}
VECTOR2I
PNS_LINE
::
snapToNeighbourSegments
(
const
SHAPE_LINE_CHAIN
&
aPath
,
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aThreshold
)
const
VECTOR2I
PNS_LINE
::
snapToNeighbourSegments
(
const
SHAPE_LINE_CHAIN
&
aPath
,
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aThreshold
)
const
{
VECTOR2I
snap_p
[
2
];
DIRECTION_45
dragDir
(
aPath
.
CSegment
(
aIndex
)
);
int
snap_d
[
2
]
=
{
-
1
,
-
1
};
DIRECTION_45
dragDir
(
aPath
.
CSegment
(
aIndex
)
);
int
snap_d
[
2
]
=
{
-
1
,
-
1
};
if
(
aThreshold
==
0
)
return
aP
;
if
(
aIndex
>=
2
)
if
(
aIndex
>=
2
)
{
SEG
s
=
aPath
.
CSegment
(
aIndex
-
2
);
if
(
DIRECTION_45
(
s
)
==
dragDir
)
snap_d
[
0
]
=
s
.
LineDistance
(
aP
);
SEG
s
=
aPath
.
CSegment
(
aIndex
-
2
);
if
(
DIRECTION_45
(
s
)
==
dragDir
)
snap_d
[
0
]
=
s
.
LineDistance
(
aP
);
snap_p
[
0
]
=
s
.
A
;
}
if
(
aIndex
<
aPath
.
SegmentCount
()
-
2
)
if
(
aIndex
<
aPath
.
SegmentCount
()
-
2
)
{
SEG
s
=
aPath
.
CSegment
(
aIndex
+
2
);
if
(
DIRECTION_45
(
s
)
==
dragDir
)
SEG
s
=
aPath
.
CSegment
(
aIndex
+
2
);
if
(
DIRECTION_45
(
s
)
==
dragDir
)
snap_d
[
1
]
=
s
.
LineDistance
(
aP
);
snap_p
[
1
]
=
s
.
A
;
}
VECTOR2I
best
=
aP
;
int
minDist
=
INT_MAX
;
for
(
int
i
=
0
;
i
<
2
;
i
++
)
if
(
snap_d
[
i
]
>=
0
&&
snap_d
[
i
]
<
minDist
&&
snap_d
[
i
]
<=
aThreshold
)
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
if
(
snap_d
[
i
]
>=
0
&&
snap_d
[
i
]
<
minDist
&&
snap_d
[
i
]
<=
aThreshold
)
{
minDist
=
snap_d
[
i
];
best
=
snap_p
[
i
];
}
}
return
best
;
}
...
...
@@ -485,157 +513,166 @@ VECTOR2I PNS_LINE::snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const
void
PNS_LINE
::
DragSegment
(
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aSnappingThreshold
)
{
SHAPE_LINE_CHAIN
path
(
m_line
);
VECTOR2I
target
(
aP
)
;
SHAPE_LINE_CHAIN
path
(
m_line
);
VECTOR2I
target
(
aP
)
;
SEG
guideA
[
2
],
guideB
[
2
];
int
index
=
aIndex
;
target
=
snapToNeighbourSegments
(
path
,
aP
,
aIndex
,
aSnappingThreshold
);
if
(
index
==
0
)
if
(
index
==
0
)
{
path
.
Insert
(
0
,
path
.
CPoint
(
0
)
);
path
.
Insert
(
0
,
path
.
CPoint
(
0
)
);
index
++
;
}
if
(
index
==
path
.
SegmentCount
()
-
1
)
if
(
index
==
path
.
SegmentCount
()
-
1
)
{
path
.
Insert
(
path
.
PointCount
()
-
1
,
path
.
CPoint
(
-
1
)
);
path
.
Insert
(
path
.
PointCount
()
-
1
,
path
.
CPoint
(
-
1
)
);
}
SEG
dragged
=
path
.
CSegment
(
index
);
DIRECTION_45
drag_dir
(
dragged
);
SEG
dragged
=
path
.
CSegment
(
index
);
DIRECTION_45
drag_dir
(
dragged
);
SEG
s_prev
=
path
.
CSegment
(
index
-
1
);
SEG
s_next
=
path
.
CSegment
(
index
+
1
);
SEG
s_prev
=
path
.
CSegment
(
index
-
1
);
SEG
s_next
=
path
.
CSegment
(
index
+
1
);
DIRECTION_45
dir_prev
(
s_prev
);
DIRECTION_45
dir_next
(
s_next
);
DIRECTION_45
dir_prev
(
s_prev
);
DIRECTION_45
dir_next
(
s_next
);
if
(
dir_prev
==
drag_dir
)
if
(
dir_prev
==
drag_dir
)
{
dir_prev
=
dir_prev
.
Left
();
path
.
Insert
(
index
,
path
.
CPoint
(
index
)
);
path
.
Insert
(
index
,
path
.
CPoint
(
index
)
);
index
++
;
}
if
(
dir_next
==
drag_dir
)
if
(
dir_next
==
drag_dir
)
{
dir_next
=
dir_next
.
Right
();
path
.
Insert
(
index
+
1
,
path
.
CPoint
(
index
+
1
)
);
path
.
Insert
(
index
+
1
,
path
.
CPoint
(
index
+
1
)
);
}
s_prev
=
path
.
CSegment
(
index
-
1
);
s_next
=
path
.
CSegment
(
index
+
1
);
dragged
=
path
.
CSegment
(
index
);
s_prev
=
path
.
CSegment
(
index
-
1
);
s_next
=
path
.
CSegment
(
index
+
1
);
dragged
=
path
.
CSegment
(
index
);
bool
lockEndpointA
=
true
;
bool
lockEndpointB
=
true
;
if
(
aIndex
==
0
)
if
(
aIndex
==
0
)
{
if
(
!
lockEndpointA
)
if
(
!
lockEndpointA
)
guideA
[
0
]
=
guideA
[
1
]
=
SEG
(
dragged
.
A
,
dragged
.
A
+
drag_dir
.
Right
().
Right
().
ToVector
()
);
else
{
else
{
guideA
[
0
]
=
SEG
(
dragged
.
A
,
dragged
.
A
+
drag_dir
.
Right
().
ToVector
()
);
guideA
[
1
]
=
SEG
(
dragged
.
A
,
dragged
.
A
+
drag_dir
.
Left
().
ToVector
()
);
}
}
else
{
if
(
dir_prev
.
IsObtuse
(
drag_dir
))
}
else
{
if
(
dir_prev
.
IsObtuse
(
drag_dir
)
)
{
guideA
[
0
]
=
SEG
(
s_prev
.
A
,
s_prev
.
A
+
drag_dir
.
Left
().
ToVector
()
);
guideA
[
1
]
=
SEG
(
s_prev
.
A
,
s_prev
.
A
+
drag_dir
.
Right
().
ToVector
()
);
}
else
}
else
guideA
[
0
]
=
guideA
[
1
]
=
SEG
(
dragged
.
A
,
dragged
.
A
+
dir_prev
.
ToVector
()
);
}
if
(
aIndex
==
m_line
.
SegmentCount
()
-
1
)
if
(
aIndex
==
m_line
.
SegmentCount
()
-
1
)
{
if
(
!
lockEndpointB
)
if
(
!
lockEndpointB
)
guideB
[
0
]
=
guideB
[
1
]
=
SEG
(
dragged
.
B
,
dragged
.
B
+
drag_dir
.
Right
().
Right
().
ToVector
()
);
else
{
else
{
guideB
[
0
]
=
SEG
(
dragged
.
B
,
dragged
.
B
+
drag_dir
.
Right
().
ToVector
()
);
guideB
[
1
]
=
SEG
(
dragged
.
B
,
dragged
.
B
+
drag_dir
.
Left
().
ToVector
()
);
}
}
else
{
if
(
dir_next
.
IsObtuse
(
drag_dir
))
}
else
{
if
(
dir_next
.
IsObtuse
(
drag_dir
)
)
{
guideB
[
0
]
=
SEG
(
s_next
.
B
,
s_next
.
B
+
drag_dir
.
Left
().
ToVector
()
);
guideB
[
1
]
=
SEG
(
s_next
.
B
,
s_next
.
B
+
drag_dir
.
Right
().
ToVector
()
);
}
else
}
else
guideB
[
0
]
=
guideB
[
1
]
=
SEG
(
dragged
.
B
,
dragged
.
B
+
dir_next
.
ToVector
()
);
}
SEG
s_current
(
target
,
target
+
drag_dir
.
ToVector
()
);
SEG
s_current
(
target
,
target
+
drag_dir
.
ToVector
()
);
int
best_len
=
INT_MAX
;
SHAPE_LINE_CHAIN
best
;
for
(
int
i
=
0
;
i
<
2
;
i
++
)
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
for
(
int
j
=
0
;
j
<
2
;
j
++
)
for
(
int
j
=
0
;
j
<
2
;
j
++
)
{
OPT_VECTOR2I
ip1
=
s_current
.
IntersectLines
(
guideA
[
i
]
);
OPT_VECTOR2I
ip2
=
s_current
.
IntersectLines
(
guideB
[
j
]
);
OPT_VECTOR2I
ip1
=
s_current
.
IntersectLines
(
guideA
[
i
]
);
OPT_VECTOR2I
ip2
=
s_current
.
IntersectLines
(
guideB
[
j
]
);
SHAPE_LINE_CHAIN
np
;
if
(
!
ip1
||
!
ip2
)
if
(
!
ip1
||
!
ip2
)
continue
;
SEG
s1
(
s_prev
.
A
,
*
ip1
);
SEG
s2
(
*
ip1
,
*
ip2
);
SEG
s3
(
*
ip2
,
s_next
.
B
);
SEG
s1
(
s_prev
.
A
,
*
ip1
);
SEG
s2
(
*
ip1
,
*
ip2
);
SEG
s3
(
*
ip2
,
s_next
.
B
);
OPT_VECTOR2I
ip
;
if
(
ip
=
s1
.
Intersect
(
s_next
)
)
if
(
ip
=
s1
.
Intersect
(
s_next
)
)
{
np
.
Append
(
s1
.
A
);
np
.
Append
(
*
ip
);
np
.
Append
(
s_next
.
B
);
}
else
if
(
ip
=
s3
.
Intersect
(
s_prev
))
}
else
if
(
ip
=
s3
.
Intersect
(
s_prev
)
)
{
np
.
Append
(
s_prev
.
A
);
np
.
Append
(
*
ip
);
np
.
Append
(
s3
.
B
);
}
else
if
(
ip
=
s1
.
Intersect
(
s3
))
}
else
if
(
ip
=
s1
.
Intersect
(
s3
)
)
{
np
.
Append
(
s_prev
.
A
);
np
.
Append
(
*
ip
);
np
.
Append
(
s_next
.
B
);
}
else
{
}
else
{
np
.
Append
(
s_prev
.
A
);
np
.
Append
(
*
ip1
);
np
.
Append
(
*
ip2
);
np
.
Append
(
s_next
.
B
);
}
if
(
np
.
Length
()
<
best_len
)
if
(
np
.
Length
()
<
best_len
)
{
best_len
=
np
.
Length
();
best
=
np
;
}
}
}
if
(
!
lockEndpointA
&&
aIndex
==
0
)
best
.
Remove
(
0
,
0
);
if
(
!
lockEndpointB
&&
aIndex
==
m_line
.
SegmentCount
()
-
1
)
best
.
Remove
(
-
1
,
-
1
);
if
(
!
lockEndpointA
&&
aIndex
==
0
)
best
.
Remove
(
0
,
0
);
if
(
!
lockEndpointB
&&
aIndex
==
m_line
.
SegmentCount
()
-
1
)
best
.
Remove
(
-
1
,
-
1
);
if
(
m_line
.
PointCount
()
==
1
)
if
(
m_line
.
PointCount
()
==
1
)
m_line
=
best
;
else
if
(
aIndex
==
0
)
m_line
.
Replace
(
0
,
1
,
best
);
else
if
(
aIndex
==
m_line
.
SegmentCount
()
-
1
)
m_line
.
Replace
(
-
2
,
-
1
,
best
);
else
if
(
aIndex
==
0
)
m_line
.
Replace
(
0
,
1
,
best
);
else
if
(
aIndex
==
m_line
.
SegmentCount
()
-
1
)
m_line
.
Replace
(
-
2
,
-
1
,
best
);
else
m_line
.
Replace
(
aIndex
,
aIndex
+
1
,
best
);
m_line
.
Replace
(
aIndex
,
aIndex
+
1
,
best
);
m_line
.
Simplify
();
}
...
...
@@ -643,21 +680,23 @@ void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThresh
bool
PNS_LINE
::
CompareGeometry
(
const
PNS_LINE
&
aOther
)
{
return
m_line
.
CompareGeometry
(
aOther
.
m_line
);
return
m_line
.
CompareGeometry
(
aOther
.
m_line
);
}
void
PNS_LINE
::
Reverse
()
{
m_line
=
m_line
.
Reverse
();
if
(
m_segmentRefs
)
std
::
reverse
(
m_segmentRefs
->
begin
(),
m_segmentRefs
->
end
()
);
if
(
m_segmentRefs
)
std
::
reverse
(
m_segmentRefs
->
begin
(),
m_segmentRefs
->
end
()
);
}
void
PNS_LINE
::
AppendVia
(
const
PNS_VIA
&
aVia
)
void
PNS_LINE
::
AppendVia
(
const
PNS_VIA
&
aVia
)
{
if
(
aVia
.
Pos
()
==
m_line
.
CPoint
(
0
)
)
if
(
aVia
.
Pos
()
==
m_line
.
CPoint
(
0
)
)
{
Reverse
();
}
...
...
@@ -666,62 +705,73 @@ void PNS_LINE::AppendVia(const PNS_VIA& aVia)
m_via
.
SetNet
(
m_net
);
}
void
PNS_LINE
::
SetRank
(
int
aRank
)
void
PNS_LINE
::
SetRank
(
int
aRank
)
{
m_rank
=
aRank
;
if
(
m_segmentRefs
)
if
(
m_segmentRefs
)
{
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
m_segmentRefs
)
s
->
SetRank
(
aRank
);
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
m_segmentRefs
)
s
->
SetRank
(
aRank
);
}
}
int
PNS_LINE
::
Rank
()
const
{
int
min_rank
=
INT_MAX
;
int
rank
;
if
(
m_segmentRefs
)
if
(
m_segmentRefs
)
{
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
m_segmentRefs
)
min_rank
=
std
::
min
(
min_rank
,
s
->
Rank
());
rank
=
(
min_rank
==
INT_MAX
)
?
-
1
:
min_rank
;
}
else
{
min_rank
=
std
::
min
(
min_rank
,
s
->
Rank
()
);
rank
=
(
min_rank
==
INT_MAX
)
?
-
1
:
min_rank
;
}
else
{
rank
=
m_rank
;
}
return
rank
;
}
void
PNS_LINE
::
ClipVertexRange
(
int
aStart
,
int
aEnd
)
void
PNS_LINE
::
ClipVertexRange
(
int
aStart
,
int
aEnd
)
{
m_line
=
m_line
.
Slice
(
aStart
,
aEnd
);
m_line
=
m_line
.
Slice
(
aStart
,
aEnd
);
if
(
m_segmentRefs
)
if
(
m_segmentRefs
)
{
SegmentRefs
*
snew
=
new
SegmentRefs
(
m_segmentRefs
->
begin
()
+
aStart
,
m_segmentRefs
->
begin
()
+
aEnd
);
SEGMENT_REFS
*
snew
=
new
SEGMENT_REFS
(
m_segmentRefs
->
begin
()
+
aStart
,
m_segmentRefs
->
begin
()
+
aEnd
);
delete
m_segmentRefs
;
m_segmentRefs
=
snew
;
}
}
bool
PNS_LINE
::
HasLoops
()
const
{
for
(
int
i
=
0
;
i
<
PointCount
();
i
++
)
for
(
int
j
=
0
;
j
<
PointCount
();
j
++
)
for
(
int
i
=
0
;
i
<
PointCount
();
i
++
)
{
for
(
int
j
=
0
;
j
<
PointCount
();
j
++
)
{
if
(
(
std
::
abs
(
i
-
j
)
>
1
)
&&
CPoint
(
i
)
==
CPoint
(
j
)
)
if
(
(
std
::
abs
(
i
-
j
)
>
1
)
&&
CPoint
(
i
)
==
CPoint
(
j
)
)
return
true
;
}
}
return
false
;
}
void
PNS_LINE
::
ClearSegmentLinks
()
{
if
(
m_segmentRefs
)
if
(
m_segmentRefs
)
delete
m_segmentRefs
;
m_segmentRefs
=
NULL
;
}
pcbnew/router/pns_line.h
View file @
ad1b138f
...
...
@@ -57,19 +57,18 @@ class PNS_VIA;
class
PNS_LINE
:
public
PNS_ITEM
{
public
:
typedef
std
::
vector
<
PNS_SEGMENT
*>
S
egmentRefs
;
typedef
std
::
vector
<
PNS_SEGMENT
*>
S
EGMENT_REFS
;
/**
* Constructor
* Makes an empty line.
*/
PNS_LINE
()
:
PNS_ITEM
(
LINE
)
PNS_LINE
()
:
PNS_ITEM
(
LINE
)
{
m_segmentRefs
=
NULL
;
m_hasVia
=
false
;
}
PNS_LINE
(
const
PNS_LINE
&
aOther
)
;
/**
...
...
@@ -77,7 +76,6 @@ public:
* Copies properties (net, layers, etc.) from a base line and replaces the shape
* by another
**/
PNS_LINE
(
const
PNS_LINE
&
aBase
,
const
SHAPE_LINE_CHAIN
&
aLine
)
:
PNS_ITEM
(
aBase
),
m_line
(
aLine
),
...
...
@@ -92,12 +90,12 @@ public:
~
PNS_LINE
();
/// @copydoc PNS_ITEM::Clone()
virtual
PNS_LINE
*
Clone
(
)
const
;
virtual
PNS_LINE
*
Clone
()
const
;
const
PNS_LINE
&
operator
=
(
const
PNS_LINE
&
aOther
);
const
PNS_LINE
&
operator
=
(
const
PNS_LINE
&
aOther
);
///> Assigns a shape to the line (a polyline/line chain)
void
SetShape
(
const
SHAPE_LINE_CHAIN
&
aLine
)
void
SetShape
(
const
SHAPE_LINE_CHAIN
&
aLine
)
{
m_line
=
aLine
;
}
...
...
@@ -135,13 +133,13 @@ public:
///> Returns the aIdx-th point of the line
const
VECTOR2I
&
CPoint
(
int
aIdx
)
const
{
return
m_line
.
CPoint
(
aIdx
);
return
m_line
.
CPoint
(
aIdx
);
}
///> Returns the aIdx-th segment of the line
const
SEG
CSegment
(
int
aIdx
)
const
const
SEG
CSegment
(
int
aIdx
)
const
{
return
m_line
.
CSegment
(
aIdx
);
return
m_line
.
CSegment
(
aIdx
);
}
///> Sets line width
...
...
@@ -169,14 +167,14 @@ public:
void
LinkSegment
(
PNS_SEGMENT
*
aSeg
)
{
if
(
!
m_segmentRefs
)
m_segmentRefs
=
new
S
egmentRefs
();
m_segmentRefs
=
new
S
EGMENT_REFS
();
m_segmentRefs
->
push_back
(
aSeg
);
}
///> Returns the list of segments from the owning node that constitute this
///> line (or NULL if the line is not linked)
S
egmentRefs
*
LinkedSegments
()
S
EGMENT_REFS
*
LinkedSegments
()
{
return
m_segmentRefs
;
}
...
...
@@ -195,9 +193,11 @@ public:
void
ClearSegmentLinks
();
///> Returns the number of segments that were assembled together to form this line.
int
LinkCount
()
const
{
if
(
!
m_segmentRefs
)
int
LinkCount
()
const
{
if
(
!
m_segmentRefs
)
return
-
1
;
return
m_segmentRefs
->
size
();
}
...
...
@@ -208,7 +208,6 @@ public:
///> Clips the line to a given range of vertices.
void
ClipVertexRange
(
int
aStart
,
int
aEnd
);
///> Returns the number of corners of angles specified by mask aAngles.
int
CountCorners
(
int
aAngles
);
...
...
@@ -218,12 +217,11 @@ public:
///> aWalkaroundPath = path around the obstacle
///> aPostPath = past from obstacle till the end
///> aCW = whether to walk around in clockwise or counter-clockwise direction.
bool
Walkaround
(
SHAPE_LINE_CHAIN
obstacle
,
SHAPE_LINE_CHAIN
&
pre
,
SHAPE_LINE_CHAIN
&
walk
,
SHAPE_LINE_CHAIN
&
post
,
bool
cw
)
const
;
bool
Walkaround
(
SHAPE_LINE_CHAIN
aObstacle
,
SHAPE_LINE_CHAIN
&
aPre
,
SHAPE_LINE_CHAIN
&
aWalk
,
SHAPE_LINE_CHAIN
&
aPost
,
bool
aCw
)
const
;
void
Walkaround
(
const
SHAPE_LINE_CHAIN
&
aObstacle
,
SHAPE_LINE_CHAIN
&
aPath
,
...
...
@@ -241,29 +239,31 @@ public:
const
PNS_VIA
&
Via
()
const
{
return
m_via
;
}
virtual
void
Mark
(
int
aMarker
);
virtual
void
Mark
(
int
aMarker
);
virtual
void
Unmark
();
virtual
int
Marker
()
const
;
void
DragSegment
(
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aSnappingThreshold
=
0
);
void
DragCorner
(
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aSnappingThreshold
=
0
);
void
DragSegment
(
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aSnappingThreshold
=
0
);
void
DragCorner
(
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aSnappingThreshold
=
0
);
void
SetRank
(
int
aRank
);
void
SetRank
(
int
aRank
);
int
Rank
()
const
;
bool
HasLoops
()
const
;
private
:
VECTOR2I
snapToNeighbourSegments
(
const
SHAPE_LINE_CHAIN
&
aPath
,
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aThreshold
)
const
;
VECTOR2I
snap
ToNeighbourSegments
(
const
SHAPE_LINE_CHAIN
&
aPath
,
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aThreshold
)
const
;
VECTOR2I
snapDraggedCorner
(
const
SHAPE_LINE_CHAIN
&
aPath
,
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aThreshold
)
const
;
VECTOR2I
snap
DraggedCorner
(
const
SHAPE_LINE_CHAIN
&
aPath
,
const
VECTOR2I
&
aP
,
int
aIndex
,
int
aThreshold
)
const
;
///> Copies m_segmentRefs from the line aParent.
void
copyLinks
(
const
PNS_LINE
*
aParent
)
;
void
copyLinks
(
const
PNS_LINE
*
aParent
)
;
///> List of segments in the owning PNS_NODE (PNS_ITEM::m_owner) that constitute this line, or NULL
///> if the line is not a part of any node.
S
egmentRefs
*
m_segmentRefs
;
S
EGMENT_REFS
*
m_segmentRefs
;
///> The actual shape of the line
SHAPE_LINE_CHAIN
m_line
;
...
...
pcbnew/router/pns_line_placer.cpp
View file @
ad1b138f
...
...
@@ -44,7 +44,8 @@ PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) :
m_world
=
NULL
;
m_shove
=
NULL
;
m_currentNode
=
NULL
;
};
}
PNS_LINE_PLACER
::~
PNS_LINE_PLACER
()
{
...
...
@@ -52,11 +53,13 @@ PNS_LINE_PLACER::~PNS_LINE_PLACER()
delete
m_shove
;
}
void
PNS_LINE_PLACER
::
setWorld
(
PNS_NODE
*
aWorld
)
void
PNS_LINE_PLACER
::
setWorld
(
PNS_NODE
*
aWorld
)
{
m_world
=
aWorld
;
}
void
PNS_LINE_PLACER
::
AddVia
(
bool
aEnabled
,
int
aDiameter
,
int
aDrill
)
{
m_viaDiameter
=
aDiameter
;
...
...
@@ -64,11 +67,10 @@ void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill )
m_placingVia
=
aEnabled
;
}
void
PNS_LINE_PLACER
::
startPlacement
(
const
VECTOR2I
&
aStart
,
int
aNet
,
int
aWidth
,
int
aLayer
)
{
assert
(
m_world
!=
NULL
);
void
PNS_LINE_PLACER
::
startPlacement
(
const
VECTOR2I
&
aStart
,
int
aNet
,
int
aWidth
,
int
aLayer
)
{
assert
(
m_world
!=
NULL
);
m_direction
=
m_initial_direction
;
TRACE
(
1
,
"world %p, intitial-direction %s layer %d
\n
"
,
...
...
@@ -89,14 +91,14 @@ void PNS_LINE_PLACER::startPlacement( const VECTOR2I& aStart, int aNet,
m_currentMode
=
Settings
().
Mode
();
if
(
m_shove
)
if
(
m_shove
)
delete
m_shove
;
m_shove
=
NULL
;
if
(
m_currentMode
==
RM_Shove
||
m_currentMode
==
RM_Smart
)
if
(
m_currentMode
==
RM_Shove
||
m_currentMode
==
RM_Smart
)
{
m_shove
=
new
PNS_SHOVE
(
m_world
->
Branch
(),
Router
()
);
m_shove
=
new
PNS_SHOVE
(
m_world
->
Branch
(),
Router
()
);
}
m_placingVia
=
false
;
...
...
@@ -107,7 +109,7 @@ void PNS_LINE_PLACER::setInitialDirection( const DIRECTION_45& aDirection )
{
m_initial_direction
=
aDirection
;
if
(
m_tail
.
SegmentCount
()
==
0
)
if
(
m_tail
.
SegmentCount
()
==
0
)
m_direction
=
aDirection
;
}
...
...
@@ -154,6 +156,7 @@ bool PNS_LINE_PLACER::handleSelfIntersections()
m_direction
=
m_initial_direction
;
tail
.
Clear
();
head
.
Clear
();
return
true
;
}
else
...
...
@@ -176,7 +179,7 @@ bool PNS_LINE_PLACER::handlePullback()
SHAPE_LINE_CHAIN
&
head
=
m_head
.
Line
();
SHAPE_LINE_CHAIN
&
tail
=
m_tail
.
Line
();
if
(
head
.
PointCount
()
<
2
)
if
(
head
.
PointCount
()
<
2
)
return
false
;
int
n
=
tail
.
PointCount
();
...
...
@@ -201,7 +204,7 @@ bool PNS_LINE_PLACER::handlePullback()
// case 2: regardless of the current routing direction, if the tail/head
// extremities form an acute or right angle, reduce the tail by one segment
// (and hope that further iterations) will result with a cleaner trace
bool
pullback_2
=
(
angle
==
DIRECTION_45
::
ANG_RIGHT
||
angle
==
DIRECTION_45
::
ANG_ACUTE
);
bool
pullback_2
=
(
angle
==
DIRECTION_45
::
ANG_RIGHT
||
angle
==
DIRECTION_45
::
ANG_ACUTE
);
if
(
pullback_1
||
pullback_2
)
{
...
...
@@ -237,7 +240,7 @@ bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd )
int
n
=
tail
.
SegmentCount
();
if
(
head
.
SegmentCount
()
<
1
)
if
(
head
.
SegmentCount
()
<
1
)
return
false
;
// Don't attempt this for too short tails
...
...
@@ -294,10 +297,10 @@ bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd )
}
bool
PNS_LINE_PLACER
::
checkObtusity
(
const
SEG
&
a
,
const
SEG
&
b
)
const
bool
PNS_LINE_PLACER
::
checkObtusity
(
const
SEG
&
a
A
,
const
SEG
&
aB
)
const
{
const
DIRECTION_45
dir_a
(
a
);
const
DIRECTION_45
dir_b
(
b
);
const
DIRECTION_45
dir_a
(
a
A
);
const
DIRECTION_45
dir_b
(
aB
);
return
dir_a
.
IsObtuse
(
dir_b
)
||
dir_a
==
dir_b
;
}
...
...
@@ -399,6 +402,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
return
false
;
}
bool
PNS_LINE_PLACER
::
rhWalkOnly
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
)
{
SHAPE_LINE_CHAIN
line
=
m_direction
.
BuildInitialTrace
(
m_p_start
,
aP
);
...
...
@@ -412,27 +416,30 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
walkaround
.
SetSolidsOnly
(
false
);
walkaround
.
SetIterationLimit
(
Settings
().
WalkaroundIterationLimit
()
);
PNS_WALKAROUND
::
W
alkaroundStatus
wf
=
walkaround
.
Route
(
initTrack
,
walkFull
,
false
);
PNS_WALKAROUND
::
W
ALKAROUND_STATUS
wf
=
walkaround
.
Route
(
initTrack
,
walkFull
,
false
);
switch
(
Settings
().
OptimizerEffort
()
)
switch
(
Settings
().
OptimizerEffort
()
)
{
case
OE_L
ow
:
case
OE_L
OW
:
effort
=
0
;
break
;
case
OE_Medium
:
case
OE_Full
:
case
OE_MEDIUM
:
case
OE_FULL
:
effort
=
PNS_OPTIMIZER
::
MERGE_SEGMENTS
;
break
;
}
if
(
Settings
().
SmartPads
())
if
(
Settings
().
SmartPads
()
)
effort
|=
PNS_OPTIMIZER
::
SMART_PADS
;
if
(
wf
==
PNS_WALKAROUND
::
STUCK
)
{
walkFull
=
walkFull
.
ClipToNearestObstacle
(
m_currentNode
);
rv
=
true
;
}
else
if
(
m_placingVia
&&
viaOk
)
{
}
else
if
(
m_placingVia
&&
viaOk
)
{
PNS_LAYERSET
allLayers
(
0
,
15
);
PNS_VIA
v1
(
walkFull
.
CPoint
(
-
1
),
allLayers
,
m_viaDiameter
);
walkFull
.
AppendVia
(
v1
);
...
...
@@ -440,7 +447,7 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
PNS_OPTIMIZER
::
Optimize
(
&
walkFull
,
effort
,
m_currentNode
);
if
(
m_currentNode
->
CheckColliding
(
&
walkFull
)
)
if
(
m_currentNode
->
CheckColliding
(
&
walkFull
)
)
{
TRACEn
(
0
,
"strange, walk line colliding
\n
"
);
}
...
...
@@ -451,9 +458,10 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
return
rv
;
}
bool
PNS_LINE_PLACER
::
rhMarkObstacles
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
)
bool
PNS_LINE_PLACER
::
rhMarkObstacles
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
)
{
m_head
.
SetShape
(
m_direction
.
BuildInitialTrace
(
m_p_start
,
aP
)
);
m_head
.
SetShape
(
m_direction
.
BuildInitialTrace
(
m_p_start
,
aP
)
);
if
(
m_placingVia
)
{
...
...
@@ -467,6 +475,7 @@ bool PNS_LINE_PLACER::rhMarkObstacles ( const VECTOR2I& aP, PNS_LINE& aNewHead )
return
m_currentNode
->
CheckColliding
(
&
m_head
);
}
bool
PNS_LINE_PLACER
::
rhShoveOnly
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
)
{
SHAPE_LINE_CHAIN
line
=
m_direction
.
BuildInitialTrace
(
m_p_start
,
aP
);
...
...
@@ -482,7 +491,7 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
walkaround
.
SetSolidsOnly
(
true
);
walkaround
.
SetIterationLimit
(
10
);
PNS_WALKAROUND
::
W
alkaroundStatus
stat_solids
=
walkaround
.
Route
(
initTrack
,
walkSolids
);
PNS_WALKAROUND
::
W
ALKAROUND_STATUS
stat_solids
=
walkaround
.
Route
(
initTrack
,
walkSolids
);
optimizer
.
SetEffortLevel
(
PNS_OPTIMIZER
::
MERGE_SEGMENTS
);
optimizer
.
SetCollisionMask
(
PNS_ITEM
::
SOLID
);
...
...
@@ -513,13 +522,13 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
// in certain, uncommon cases there may be loops in the head+tail, In such case, we don't shove to avoid
// screwing up the database.
if
(
l
.
HasLoops
()
)
if
(
l
.
HasLoops
()
)
{
aNewHead
=
m_head
;
return
false
;
}
PNS_SHOVE
::
S
hoveStatus
status
=
m_shove
->
ShoveLines
(
l
);
PNS_SHOVE
::
S
HOVE_STATUS
status
=
m_shove
->
ShoveLines
(
l
);
m_currentNode
=
m_shove
->
CurrentNode
();
...
...
@@ -546,10 +555,10 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
return
false
;
}
return
false
;
}
bool
PNS_LINE_PLACER
::
routeHead
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
)
{
switch
(
m_currentMode
)
...
...
@@ -570,18 +579,18 @@ bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead )
bool
PNS_LINE_PLACER
::
optimizeTailHeadTransition
()
{
PNS_LINE
tmp
=
Trace
();
if
(
PNS_OPTIMIZER
::
Optimize
(
&
tmp
,
PNS_OPTIMIZER
::
FANOUT_CLEANUP
,
m_currentNode
)
)
if
(
PNS_OPTIMIZER
::
Optimize
(
&
tmp
,
PNS_OPTIMIZER
::
FANOUT_CLEANUP
,
m_currentNode
)
)
{
if
(
tmp
.
SegmentCount
()
<
1
)
if
(
tmp
.
SegmentCount
()
<
1
)
return
false
;
m_head
=
tmp
;
m_p_start
=
tmp
.
CLine
().
CPoint
(
0
);
m_direction
=
DIRECTION_45
(
tmp
.
CSegment
(
0
)
);
m_tail
.
Line
().
Clear
();
return
true
;
}
...
...
@@ -611,7 +620,7 @@ bool PNS_LINE_PLACER::optimizeTailHeadTransition()
// If so, replace the (threshold) last tail points and the head with
// the optimized line
if
(
PNS_OPTIMIZER
::
Optimize
(
&
new_head
,
PNS_OPTIMIZER
::
MERGE_OBTUSE
,
m_currentNode
)
)
if
(
PNS_OPTIMIZER
::
Optimize
(
&
new_head
,
PNS_OPTIMIZER
::
MERGE_OBTUSE
,
m_currentNode
)
)
{
PNS_LINE
tmp
(
m_tail
,
opt_line
);
...
...
@@ -702,22 +711,26 @@ const PNS_LINE PNS_LINE_PLACER::Trace() const
return
tmp
;
}
const
PNS_ITEMSET
PNS_LINE_PLACER
::
Traces
()
{
m_currentTrace
=
Trace
();
return
PNS_ITEMSET
(
&
m_currentTrace
);
}
void
PNS_LINE_PLACER
::
FlipPosture
()
{
m_initial_direction
=
m_initial_direction
.
Right
();
m_direction
=
m_direction
.
Right
();
}
PNS_NODE
*
PNS_LINE_PLACER
::
CurrentNode
(
bool
aLoopsRemoved
)
const
PNS_NODE
*
PNS_LINE_PLACER
::
CurrentNode
(
bool
aLoopsRemoved
)
const
{
if
(
aLoopsRemoved
&&
m_lastNode
)
if
(
aLoopsRemoved
&&
m_lastNode
)
return
m_lastNode
;
return
m_currentNode
;
}
...
...
@@ -747,16 +760,19 @@ void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, co
}
}
void
PNS_LINE_PLACER
::
SetLayer
(
int
aLayer
)
{
m_currentLayer
=
aLayer
;
}
void
PNS_LINE_PLACER
::
SetWidth
(
int
aWidth
)
{
m_currentWidth
=
aWidth
;
}
void
PNS_LINE_PLACER
::
Start
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aStartItem
)
{
VECTOR2I
p
(
aP
);
...
...
@@ -783,7 +799,6 @@ void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
m_currentEnd
=
p
;
m_currentNet
=
net
;
PNS_NODE
*
rootNode
=
Router
()
->
GetWorld
()
->
Branch
();
if
(
splitSeg
)
...
...
@@ -801,7 +816,7 @@ void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
VECTOR2I
p
=
aP
;
int
eiDepth
=
-
1
;
if
(
aEndItem
&&
aEndItem
->
Owner
()
)
if
(
aEndItem
&&
aEndItem
->
Owner
()
)
eiDepth
=
aEndItem
->
Owner
()
->
Depth
();
if
(
m_lastNode
)
...
...
@@ -814,26 +829,27 @@ void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
current
=
Trace
();
if
(
!
current
.
PointCount
()
)
if
(
!
current
.
PointCount
()
)
m_currentEnd
=
m_p_start
;
else
m_currentEnd
=
current
.
CLine
().
CPoint
(
-
1
);
PNS_NODE
*
latestNode
=
m_currentNode
;
m_lastNode
=
latestNode
->
Branch
();
if
(
eiDepth
>=
0
&&
aEndItem
&&
latestNode
->
Depth
()
>
eiDepth
&&
current
.
SegmentCount
()
&&
current
.
CPoint
(
-
1
)
==
aP
)
if
(
eiDepth
>=
0
&&
aEndItem
&&
latestNode
->
Depth
()
>
eiDepth
&&
current
.
SegmentCount
()
&&
current
.
CPoint
(
-
1
)
==
aP
)
{
splitAdjacentSegments
(
m_lastNode
,
aEndItem
,
current
.
CPoint
(
-
1
)
);
if
(
Settings
().
RemoveLoops
())
splitAdjacentSegments
(
m_lastNode
,
aEndItem
,
current
.
CPoint
(
-
1
)
);
if
(
Settings
().
RemoveLoops
()
)
removeLoops
(
m_lastNode
,
&
current
);
}
updateLeadingRatLine
();
}
bool
PNS_LINE_PLACER
::
FixRoute
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aEndItem
)
{
bool
realEnd
=
false
;
...
...
@@ -861,13 +877,11 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
if
(
aEndItem
&&
m_currentNet
>=
0
&&
m_currentNet
==
aEndItem
->
Net
()
)
realEnd
=
true
;
if
(
realEnd
||
m_placingVia
)
if
(
realEnd
||
m_placingVia
)
lastV
=
l
.
SegmentCount
();
else
lastV
=
std
::
max
(
1
,
l
.
SegmentCount
()
-
1
);
PNS_SEGMENT
*
lastSeg
=
NULL
;
for
(
int
i
=
0
;
i
<
lastV
;
i
++
)
...
...
@@ -883,14 +897,14 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
if
(
pl
.
EndsWithVia
()
)
m_lastNode
->
Add
(
pl
.
Via
().
Clone
()
);
if
(
realEnd
)
if
(
realEnd
)
simplifyNewLine
(
m_lastNode
,
lastSeg
);
Router
()
->
CommitRouting
(
m_lastNode
);
m_lastNode
=
NULL
;
if
(
!
realEnd
)
if
(
!
realEnd
)
{
setInitialDirection
(
d_last
);
VECTOR2I
p_start
=
m_placingVia
?
p_last
:
p_pre_last
;
...
...
@@ -908,20 +922,19 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
return
realEnd
;
}
void
PNS_LINE_PLACER
::
removeLoops
(
PNS_NODE
*
aNode
,
PNS_LINE
*
aLatest
)
{
if
(
!
aLatest
->
SegmentCount
()
)
if
(
!
aLatest
->
SegmentCount
()
)
return
;
aNode
->
Add
(
aLatest
,
true
);
for
(
int
s
=
0
;
s
<
aLatest
->
SegmentCount
();
s
++
)
for
(
int
s
=
0
;
s
<
aLatest
->
SegmentCount
();
s
++
)
{
PNS_SEGMENT
*
seg
=
(
*
aLatest
->
LinkedSegments
())[
s
];
PNS_LINE
*
ourLine
=
aNode
->
AssembleLine
(
seg
)
;
PNS_SEGMENT
*
seg
=
(
*
aLatest
->
LinkedSegments
()
)[
s
];
PNS_LINE
*
ourLine
=
aNode
->
AssembleLine
(
seg
);
PNS_JOINT
a
,
b
;
std
::
vector
<
PNS_LINE
*>
lines
;
aNode
->
FindLineEnds
(
ourLine
,
a
,
b
);
...
...
@@ -944,15 +957,15 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
{
Router
()
->
DisplayDebugLine
(
line
->
CLine
(),
-
1
,
10000
);
for
(
int
i
=
0
;
i
<
line
->
PointCount
();
i
++
)
Router
()
->
DisplayDebugPoint
(
line
->
CPoint
(
i
),
-
1
);
for
(
int
i
=
0
;
i
<
line
->
PointCount
();
i
++
)
Router
()
->
DisplayDebugPoint
(
line
->
CPoint
(
i
),
-
1
);
aNode
->
Remove
(
line
);
removedCount
++
;
}
}
TRACE
(
0
,
"total segs removed: %d/%d
\n
"
,
removedCount
%
total
);
TRACE
(
0
,
"total segs removed: %d/%d
\n
"
,
removedCount
%
total
);
delete
ourLine
;
}
...
...
@@ -960,13 +973,15 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
aNode
->
Remove
(
aLatest
);
}
void
PNS_LINE_PLACER
::
simplifyNewLine
(
PNS_NODE
*
aNode
,
PNS_SEGMENT
*
aLatest
)
void
PNS_LINE_PLACER
::
simplifyNewLine
(
PNS_NODE
*
aNode
,
PNS_SEGMENT
*
aLatest
)
{
PNS_LINE
*
l
=
aNode
->
AssembleLine
(
aLatest
)
;
PNS_LINE
*
l
=
aNode
->
AssembleLine
(
aLatest
)
;
SHAPE_LINE_CHAIN
simplified
(
l
->
CLine
()
);
simplified
.
Simplify
();
if
(
simplified
.
PointCount
()
!=
l
->
PointCount
()
)
if
(
simplified
.
PointCount
()
!=
l
->
PointCount
()
)
{
std
::
auto_ptr
<
PNS_LINE
>
lnew
(
l
->
Clone
()
);
aNode
->
Remove
(
l
);
...
...
@@ -975,6 +990,7 @@ void PNS_LINE_PLACER::simplifyNewLine ( PNS_NODE *aNode, PNS_SEGMENT *aLatest )
}
}
void
PNS_LINE_PLACER
::
UpdateSizes
(
const
PNS_ROUTING_SETTINGS
&
aSettings
)
{
int
trackWidth
=
aSettings
.
GetTrackWidth
();
...
...
@@ -986,29 +1002,31 @@ void PNS_LINE_PLACER::UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings )
m_viaDrill
=
aSettings
.
GetViaDrill
();
}
void
PNS_LINE_PLACER
::
updateLeadingRatLine
()
{
PNS_LINE
current
=
Trace
();
if
(
!
current
.
PointCount
()
)
if
(
!
current
.
PointCount
()
)
return
;
std
::
auto_ptr
<
PNS_NODE
>
tmpNode
(
m_lastNode
->
Branch
()
);
tmpNode
->
Add
(
&
current
);
PNS_JOINT
*
jt
=
tmpNode
->
FindJoint
(
current
.
CPoint
(
-
1
),
current
.
Layers
().
Start
(),
current
.
Net
()
);
PNS_JOINT
*
jt
=
tmpNode
->
FindJoint
(
current
.
CPoint
(
-
1
),
current
.
Layers
().
Start
(),
current
.
Net
()
);
if
(
!
jt
)
if
(
!
jt
)
return
;
int
anchor
;
PNS_ITEM
*
it
=
tmpNode
->
NearestUnconnectedItem
(
jt
,
&
anchor
);
PNS_ITEM
*
it
=
tmpNode
->
NearestUnconnectedItem
(
jt
,
&
anchor
);
if
(
it
)
if
(
it
)
{
SHAPE_LINE_CHAIN
lc
;
lc
.
Append
(
current
.
CPoint
(
-
1
)
);
lc
.
Append
(
it
->
Anchor
(
anchor
)
);
lc
.
Append
(
current
.
CPoint
(
-
1
)
);
lc
.
Append
(
it
->
Anchor
(
anchor
)
);
Router
()
->
DisplayDebugLine
(
lc
,
5
,
10000
);
}
}
pcbnew/router/pns_line_placer.h
View file @
ad1b138f
...
...
@@ -46,7 +46,7 @@ class PNS_ROUTER_BASE;
class
PNS_LINE_PLACER
:
public
PNS_ALGO_BASE
{
public
:
PNS_LINE_PLACER
(
PNS_ROUTER
*
aRouter
);
PNS_LINE_PLACER
(
PNS_ROUTER
*
aRouter
);
~
PNS_LINE_PLACER
();
/**
...
...
@@ -92,14 +92,14 @@ public:
*
* Sets the current routing layer.
*/
void
SetLayer
(
int
aLayer
);
void
SetLayer
(
int
aLayer
);
/**
* Function SetWidth()
*
* Sets the current track width.
*/
void
SetWidth
(
int
aWidth
);
void
SetWidth
(
int
aWidth
);
/**
* Function Head()
...
...
@@ -167,7 +167,7 @@ public:
*
* Returns the most recent world state.
*/
PNS_NODE
*
CurrentNode
(
bool
aLoopsRemoved
=
false
)
const
;
PNS_NODE
*
CurrentNode
(
bool
aLoopsRemoved
=
false
)
const
;
/**
* Function FlipPosture()
...
...
@@ -185,7 +185,6 @@ public:
*/
void
UpdateSizes
(
const
PNS_ROUTING_SETTINGS
&
aSettings
);
private
:
/**
* Function route()
...
...
@@ -197,7 +196,6 @@ private:
* @param aP ending point of current route.
* @return true, if the routing is complete.
*/
bool
route
(
const
VECTOR2I
&
aP
);
/**
...
...
@@ -214,7 +212,7 @@ private:
*
* Sets the board to route.
*/
void
setWorld
(
PNS_NODE
*
aWorld
);
void
setWorld
(
PNS_NODE
*
aWorld
);
/**
* Function startPlacement()
...
...
@@ -268,9 +266,9 @@ private:
*
* Helper function, checking if segments a and b form an obtuse angle
* (in 45-degree regime).
* @return true, if angle (a
, b
) is obtuse
* @return true, if angle (a
A, aB
) is obtuse
*/
bool
checkObtusity
(
const
SEG
&
a
,
const
SEG
&
b
)
const
;
bool
checkObtusity
(
const
SEG
&
a
A
,
const
SEG
&
aB
)
const
;
/**
* Function handleSelfIntersections()
...
...
@@ -339,16 +337,15 @@ private:
*/
void
routeStep
(
const
VECTOR2I
&
aP
);
///
<
route step, walkaround mode
///
>
route step, walkaround mode
bool
rhWalkOnly
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
);
///
<
route step, shove mode
///
>
route step, shove mode
bool
rhShoveOnly
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
);
///
<
route step, mark obstacles mode
///
>
route step, mark obstacles mode
bool
rhMarkObstacles
(
const
VECTOR2I
&
aP
,
PNS_LINE
&
aNewHead
);
///> current routing direction
DIRECTION_45
m_direction
;
...
...
@@ -399,7 +396,6 @@ private:
PNS_LINE
m_currentTrace
;
PNS_MODE
m_currentMode
;
};
#endif // __PNS_LINE_PLACER_H
pcbnew/router/pns_logger.cpp
View file @
ad1b138f
...
...
@@ -38,69 +38,76 @@ PNS_LOGGER::PNS_LOGGER( )
PNS_LOGGER
::~
PNS_LOGGER
()
{
}
void
PNS_LOGGER
::
Clear
()
{
m_theLog
.
str
(
std
::
string
()
);
m_theLog
.
str
(
std
::
string
()
);
m_groupOpened
=
false
;
}
void
PNS_LOGGER
::
NewGroup
(
const
std
::
string
&
name
,
int
iter
)
void
PNS_LOGGER
::
NewGroup
(
const
std
::
string
&
aName
,
int
aIter
)
{
if
(
m_groupOpened
)
if
(
m_groupOpened
)
m_theLog
<<
"endgroup"
<<
std
::
endl
;
m_theLog
<<
"group "
<<
name
<<
" "
<<
iter
<<
std
::
endl
;
m_theLog
<<
"group "
<<
aName
<<
" "
<<
aIter
<<
std
::
endl
;
m_groupOpened
=
true
;
}
void
PNS_LOGGER
::
EndGroup
()
{
if
(
!
m_groupOpened
)
if
(
!
m_groupOpened
)
return
;
m_groupOpened
=
false
;
m_theLog
<<
"endgroup"
<<
std
::
endl
;
}
void
PNS_LOGGER
::
Log
(
const
PNS_ITEM
*
item
,
int
kind
,
const
std
::
string
name
)
void
PNS_LOGGER
::
Log
(
const
PNS_ITEM
*
aItem
,
int
aKind
,
const
std
::
string
aName
)
{
m_theLog
<<
"item "
<<
kind
<<
" "
<<
name
<<
" "
;
m_theLog
<<
item
->
Net
()
<<
" "
<<
item
->
Layers
().
Start
()
<<
" "
<<
item
->
Layers
().
End
()
<<
" "
<<
item
->
Marker
()
<<
" "
<<
item
->
Rank
();
m_theLog
<<
"aItem "
<<
aKind
<<
" "
<<
aName
<<
" "
;
m_theLog
<<
aItem
->
Net
()
<<
" "
<<
aItem
->
Layers
().
Start
()
<<
" "
<<
aItem
->
Layers
().
End
()
<<
" "
<<
aItem
->
Marker
()
<<
" "
<<
aItem
->
Rank
();
switch
(
item
->
Kind
()
)
switch
(
aItem
->
Kind
()
)
{
case
PNS_ITEM
:
:
LINE
:
{
PNS_LINE
*
l
=
(
PNS_LINE
*
)
i
tem
;
PNS_LINE
*
l
=
(
PNS_LINE
*
)
aI
tem
;
m_theLog
<<
" line "
;
m_theLog
<<
l
->
Width
()
<<
" "
<<
(
l
->
EndsWithVia
()
?
1
:
0
)
<<
" "
;
m_theLog
<<
l
->
Width
()
<<
" "
<<
(
l
->
EndsWithVia
()
?
1
:
0
)
<<
" "
;
dumpShape
(
l
->
Shape
()
);
m_theLog
<<
std
::
endl
;
break
;
}
case
PNS_ITEM
:
:
VIA
:
{
m_theLog
<<
" via 0 0 "
;
dumpShape
(
i
tem
->
Shape
()
);
dumpShape
(
aI
tem
->
Shape
()
);
m_theLog
<<
std
::
endl
;
break
;
}
case
PNS_ITEM
:
:
SEGMENT
:
{
PNS_SEGMENT
*
s
=
(
PNS_SEGMENT
*
)
i
tem
;
PNS_SEGMENT
*
s
=
(
PNS_SEGMENT
*
)
aI
tem
;
m_theLog
<<
" line "
;
m_theLog
<<
s
->
Width
()
<<
" 0 linechain 2 0 "
<<
s
->
Seg
().
A
.
x
<<
" "
<<
s
->
Seg
().
A
.
y
<<
" "
<<
s
->
Seg
().
B
.
x
<<
" "
<<
s
->
Seg
().
B
.
y
<<
std
::
endl
;
m_theLog
<<
s
->
Width
()
<<
" 0 linechain 2 0 "
<<
s
->
Seg
().
A
.
x
<<
" "
<<
s
->
Seg
().
A
.
y
<<
" "
<<
s
->
Seg
().
B
.
x
<<
" "
<<
s
->
Seg
().
B
.
y
<<
std
::
endl
;
break
;
}
case
PNS_ITEM
:
:
SOLID
:
{
PNS_SOLID
*
s
=
(
PNS_SOLID
*
)
i
tem
;
PNS_SOLID
*
s
=
(
PNS_SOLID
*
)
aI
tem
;
m_theLog
<<
" solid 0 0 "
;
dumpShape
(
s
->
Shape
()
);
dumpShape
(
s
->
Shape
()
);
m_theLog
<<
std
::
endl
;
break
;
}
...
...
@@ -110,64 +117,74 @@ void PNS_LOGGER::Log ( const PNS_ITEM *item, int kind, const std::string name )
}
}
void
PNS_LOGGER
::
Log
(
const
SHAPE_LINE_CHAIN
*
l
,
int
kind
,
const
std
::
string
name
)
void
PNS_LOGGER
::
Log
(
const
SHAPE_LINE_CHAIN
*
aL
,
int
aKind
,
const
std
::
string
aName
)
{
m_theLog
<<
"item "
<<
kind
<<
" "
<<
n
ame
<<
" "
;
m_theLog
<<
"item "
<<
aKind
<<
" "
<<
aN
ame
<<
" "
;
m_theLog
<<
0
<<
" "
<<
0
<<
" "
<<
0
<<
" "
<<
0
<<
" "
<<
0
;
m_theLog
<<
" line "
;
m_theLog
<<
0
<<
" "
<<
0
<<
" "
;
dumpShape
(
l
);
dumpShape
(
aL
);
m_theLog
<<
std
::
endl
;
}
void
PNS_LOGGER
::
Log
(
const
VECTOR2I
&
start
,
const
VECTOR2I
&
end
,
int
kind
,
const
std
::
string
name
)
{
void
PNS_LOGGER
::
Log
(
const
VECTOR2I
&
aStart
,
const
VECTOR2I
&
aEnd
,
int
aKind
,
const
std
::
string
aName
)
{
}
void
PNS_LOGGER
::
dumpShape
(
const
SHAPE
*
sh
)
void
PNS_LOGGER
::
dumpShape
(
const
SHAPE
*
aSh
)
{
switch
(
sh
->
Type
()
)
switch
(
aSh
->
Type
()
)
{
case
SH_LINE_CHAIN
:
{
const
SHAPE_LINE_CHAIN
*
lc
=
(
const
SHAPE_LINE_CHAIN
*
)
sh
;
m_theLog
<<
"linechain "
<<
lc
->
PointCount
()
<<
" "
<<
(
lc
->
IsClosed
()
?
1
:
0
)
<<
" "
;
for
(
int
i
=
0
;
i
<
lc
->
PointCount
();
i
++
)
m_theLog
<<
lc
->
CPoint
(
i
).
x
<<
" "
<<
lc
->
CPoint
(
i
).
y
<<
" "
;
const
SHAPE_LINE_CHAIN
*
lc
=
(
const
SHAPE_LINE_CHAIN
*
)
aSh
;
m_theLog
<<
"linechain "
<<
lc
->
PointCount
()
<<
" "
<<
(
lc
->
IsClosed
()
?
1
:
0
)
<<
" "
;
for
(
int
i
=
0
;
i
<
lc
->
PointCount
();
i
++
)
m_theLog
<<
lc
->
CPoint
(
i
).
x
<<
" "
<<
lc
->
CPoint
(
i
).
y
<<
" "
;
break
;
}
case
SH_CIRCLE
:
{
const
SHAPE_CIRCLE
*
c
=
(
const
SHAPE_CIRCLE
*
)
s
h
;
const
SHAPE_CIRCLE
*
c
=
(
const
SHAPE_CIRCLE
*
)
aS
h
;
m_theLog
<<
"circle "
<<
c
->
GetCenter
().
x
<<
" "
<<
c
->
GetCenter
().
y
<<
" "
<<
c
->
GetRadius
();
break
;
}
case
SH_RECT
:
{
const
SHAPE_RECT
*
r
=
(
const
SHAPE_RECT
*
)
sh
;
m_theLog
<<
"rect "
<<
r
->
GetPosition
().
x
<<
" "
<<
r
->
GetPosition
().
y
<<
" "
<<
r
->
GetSize
().
x
<<
" "
<<
r
->
GetSize
().
y
;
const
SHAPE_RECT
*
r
=
(
const
SHAPE_RECT
*
)
aSh
;
m_theLog
<<
"rect "
<<
r
->
GetPosition
().
x
<<
" "
<<
r
->
GetPosition
().
y
<<
" "
<<
r
->
GetSize
().
x
<<
" "
<<
r
->
GetSize
().
y
;
break
;
}
case
SH_SEGMENT
:
{
const
SHAPE_SEGMENT
*
s
=
(
const
SHAPE_SEGMENT
*
)
sh
;
m_theLog
<<
"linechain 2 0 "
<<
s
->
GetSeg
().
A
.
x
<<
" "
<<
s
->
GetSeg
().
A
.
y
<<
" "
<<
s
->
GetSeg
().
B
.
x
<<
" "
<<
s
->
GetSeg
().
B
.
y
;
const
SHAPE_SEGMENT
*
s
=
(
const
SHAPE_SEGMENT
*
)
aSh
;
m_theLog
<<
"linechain 2 0 "
<<
s
->
GetSeg
().
A
.
x
<<
" "
<<
s
->
GetSeg
().
A
.
y
<<
" "
<<
s
->
GetSeg
().
B
.
x
<<
" "
<<
s
->
GetSeg
().
B
.
y
;
break
;
}
default
:
break
;
}
}
void
PNS_LOGGER
::
Save
(
const
std
::
string
&
f
ilename
)
void
PNS_LOGGER
::
Save
(
const
std
::
string
&
aF
ilename
)
{
EndGroup
();
FILE
*
f
=
fopen
(
filename
.
c_str
(),
"wb"
);
printf
(
"Saving to '%s' [%p]
\n
"
,
filename
.
c_str
(),
f
);
FILE
*
f
=
fopen
(
aFilename
.
c_str
(),
"wb"
);
printf
(
"Saving to '%s' [%p]
\n
"
,
aFilename
.
c_str
(),
f
);
const
std
::
string
s
=
m_theLog
.
str
();
fwrite
(
s
.
c_str
(),
1
,
s
.
length
(),
f
);
fclose
(
f
);
fwrite
(
s
.
c_str
(),
1
,
s
.
length
(),
f
);
fclose
(
f
);
}
pcbnew/router/pns_logger.h
View file @
ad1b138f
...
...
@@ -32,24 +32,25 @@ class PNS_ITEM;
class
SHAPE_LINE_CHAIN
;
class
SHAPE
;
class
PNS_LOGGER
{
class
PNS_LOGGER
{
public
:
PNS_LOGGER
();
~
PNS_LOGGER
();
void
Save
(
const
std
::
string
&
filename
);
void
Save
(
const
std
::
string
&
aFilename
);
void
Clear
();
void
NewGroup
(
const
std
::
string
&
name
,
int
iter
=
0
);
void
NewGroup
(
const
std
::
string
&
aName
,
int
aIter
=
0
);
void
EndGroup
();
void
Log
(
const
PNS_ITEM
*
item
,
int
kind
=
0
,
const
std
::
string
name
=
std
::
string
()
);
void
Log
(
const
SHAPE_LINE_CHAIN
*
l
,
int
kind
=
0
,
const
std
::
string
name
=
std
::
string
()
);
void
Log
(
const
VECTOR2I
&
start
,
const
VECTOR2I
&
end
,
int
kind
=
0
,
const
std
::
string
name
=
std
::
string
()
);
private
:
void
Log
(
const
PNS_ITEM
*
aItem
,
int
aKind
=
0
,
const
std
::
string
aName
=
std
::
string
()
);
void
Log
(
const
SHAPE_LINE_CHAIN
*
aL
,
int
aKind
=
0
,
const
std
::
string
aName
=
std
::
string
()
);
void
Log
(
const
VECTOR2I
&
aStart
,
const
VECTOR2I
&
aEnd
,
int
aKind
=
0
,
const
std
::
string
aName
=
std
::
string
()
);
void
dumpShape
(
const
SHAPE
*
sh
);
private
:
void
dumpShape
(
const
SHAPE
*
aSh
);
bool
m_groupOpened
;
std
::
stringstream
m_theLog
;
...
...
pcbnew/router/pns_node.cpp
View file @
ad1b138f
...
...
@@ -53,11 +53,13 @@ PNS_NODE::PNS_NODE()
m_parent
=
NULL
;
m_maxClearance
=
800000
;
// fixme: depends on how thick traces are.
m_index
=
new
PNS_INDEX
;
#ifdef DEBUG
allocNodes
.
insert
(
this
);
#endif
}
PNS_NODE
::~
PNS_NODE
()
{
TRACE
(
0
,
"PNS_NODE::delete %p"
,
this
);
...
...
@@ -69,7 +71,6 @@ PNS_NODE::~PNS_NODE()
}
#ifdef DEBUG
if
(
allocNodes
.
find
(
this
)
==
allocNodes
.
end
()
)
{
TRACEn
(
0
,
"attempting to free an already-free'd node.
\n
"
);
...
...
@@ -77,31 +78,31 @@ PNS_NODE::~PNS_NODE()
}
allocNodes
.
erase
(
this
);
#endif
for
(
PNS_INDEX
::
I
temSet
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
for
(
PNS_INDEX
::
I
TEM_SET
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
{
if
(
(
*
i
)
->
BelongsTo
(
this
)
)
delete
*
i
;
}
unlinkParent
();
delete
m_index
;
}
int
PNS_NODE
::
GetClearance
(
const
PNS_ITEM
*
a
,
const
PNS_ITEM
*
b
)
const
int
PNS_NODE
::
GetClearance
(
const
PNS_ITEM
*
a
A
,
const
PNS_ITEM
*
aB
)
const
{
return
(
*
m_clearanceFunctor
)(
a
,
b
);
return
(
*
m_clearanceFunctor
)(
a
A
,
aB
);
}
PNS_NODE
*
PNS_NODE
::
Branch
()
{
PNS_NODE
*
child
=
new
PNS_NODE
;
TRACE
(
0
,
"PNS_NODE::branch %p (parent %p)"
,
child
%
this
);
m_children
.
push_back
(
child
);
child
->
m_depth
=
m_depth
+
1
;
...
...
@@ -114,10 +115,9 @@ PNS_NODE* PNS_NODE::Branch()
// to stored items.
if
(
!
isRoot
()
)
{
J
ointMap
::
iterator
j
;
J
OINT_MAP
::
iterator
j
;
for
(
PNS_INDEX
::
ItemSet
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
for
(
PNS_INDEX
::
ITEM_SET
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
child
->
m_index
->
Add
(
*
i
);
child
->
m_joints
=
m_joints
;
...
...
@@ -150,7 +150,7 @@ void PNS_NODE::unlinkParent()
// function object that visits potential obstacles and performs
// the actual collision refining
struct
PNS_NODE
::
obstacleVisitor
struct
PNS_NODE
::
OBSTACLE_VISITOR
{
///> node we are searching in (either root or a branch)
PNS_NODE
*
m_node
;
...
...
@@ -159,7 +159,7 @@ struct PNS_NODE::obstacleVisitor
PNS_NODE
*
m_override
;
///> list of encountered obstacles
O
bstacles
&
m_tab
;
O
BSTACLES
&
m_tab
;
///> the item we are looking for collisions with
const
PNS_ITEM
*
m_item
;
...
...
@@ -176,8 +176,7 @@ struct PNS_NODE::obstacleVisitor
///> additional clearance
int
m_extraClearance
;
obstacleVisitor
(
PNS_NODE
::
Obstacles
&
aTab
,
const
PNS_ITEM
*
aItem
,
int
aKindMask
)
:
OBSTACLE_VISITOR
(
PNS_NODE
::
OBSTACLES
&
aTab
,
const
PNS_ITEM
*
aItem
,
int
aKindMask
)
:
m_tab
(
aTab
),
m_item
(
aItem
),
m_kindMask
(
aKindMask
),
...
...
@@ -185,9 +184,9 @@ struct PNS_NODE::obstacleVisitor
m_matchCount
(
0
),
m_extraClearance
(
0
)
{
if
(
aItem
->
Kind
()
==
PNS_ITEM
::
LINE
)
m_extraClearance
+=
static_cast
<
const
PNS_LINE
*>
(
aItem
)
->
Width
()
/
2
;
}
;
if
(
aItem
->
Kind
()
==
PNS_ITEM
::
LINE
)
m_extraClearance
+=
static_cast
<
const
PNS_LINE
*>
(
aItem
)
->
Width
()
/
2
;
}
void
SetCountLimit
(
int
aLimit
)
{
...
...
@@ -212,7 +211,7 @@ struct PNS_NODE::obstacleVisitor
int
clearance
=
m_extraClearance
+
m_node
->
GetClearance
(
aItem
,
m_item
);
if
(
aItem
->
Kind
()
==
PNS_ITEM
::
LINE
)
if
(
aItem
->
Kind
()
==
PNS_ITEM
::
LINE
)
clearance
+=
static_cast
<
PNS_LINE
*>
(
aItem
)
->
Width
()
/
2
;
if
(
!
aItem
->
Collide
(
m_item
,
clearance
)
)
...
...
@@ -220,7 +219,7 @@ struct PNS_NODE::obstacleVisitor
PNS_OBSTACLE
obs
;
obs
.
item
=
aItem
;
obs
.
m_
item
=
aItem
;
m_tab
.
push_back
(
obs
);
m_matchCount
++
;
...
...
@@ -234,9 +233,9 @@ struct PNS_NODE::obstacleVisitor
int
PNS_NODE
::
QueryColliding
(
const
PNS_ITEM
*
aItem
,
PNS_NODE
::
O
bstacles
&
aObstacles
,
int
aKindMask
,
int
aLimitCount
)
PNS_NODE
::
O
BSTACLES
&
aObstacles
,
int
aKindMask
,
int
aLimitCount
)
{
obstacleVisitor
visitor
(
aObstacles
,
aItem
,
aKindMask
);
OBSTACLE_VISITOR
visitor
(
aObstacles
,
aItem
,
aKindMask
);
#ifdef DEBUG
assert
(
allocNodes
.
find
(
this
)
!=
allocNodes
.
end
()
);
...
...
@@ -249,7 +248,7 @@ int PNS_NODE::QueryColliding( const PNS_ITEM* aItem,
m_index
->
Query
(
aItem
,
m_maxClearance
,
visitor
);
// if we haven't found enough items, look in the root branch as well.
if
(
!
isRoot
()
&&
(
visitor
.
m_matchCount
<
aLimitCount
||
aLimitCount
<
0
)
)
if
(
!
isRoot
()
&&
(
visitor
.
m_matchCount
<
aLimitCount
||
aLimitCount
<
0
)
)
{
visitor
.
SetWorld
(
m_root
,
this
);
m_root
->
m_index
->
Query
(
aItem
,
m_maxClearance
,
visitor
);
...
...
@@ -259,9 +258,9 @@ int PNS_NODE::QueryColliding( const PNS_ITEM* aItem,
}
PNS_NODE
::
O
ptObstacle
PNS_NODE
::
NearestObstacle
(
const
PNS_LINE
*
aItem
,
int
aKindMask
)
PNS_NODE
::
O
PT_OBSTACLE
PNS_NODE
::
NearestObstacle
(
const
PNS_LINE
*
aItem
,
int
aKindMask
)
{
O
bstacles
obs_list
;
O
BSTACLES
obs_list
;
bool
found_isects
=
false
;
const
SHAPE_LINE_CHAIN
&
line
=
aItem
->
CLine
();
...
...
@@ -281,13 +280,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
// if(! QueryColliding ( aItem, obs_list, aKindMask ))
if
(
!
n
)
return
O
ptObstacle
();
return
O
PT_OBSTACLE
();
PNS_LINE
&
aLine
=
(
PNS_LINE
&
)
*
aItem
;
PNS_OBSTACLE
nearest
;
nearest
.
item
=
NULL
;
nearest
.
dist_f
irst
=
INT_MAX
;
nearest
.
m_
item
=
NULL
;
nearest
.
m_distF
irst
=
INT_MAX
;
BOOST_FOREACH
(
PNS_OBSTACLE
obs
,
obs_list
)
{
...
...
@@ -296,13 +295,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
std
::
vector
<
SHAPE_LINE_CHAIN
::
INTERSECTION
>
isect_list
;
int
clearance
=
GetClearance
(
obs
.
item
,
&
aLine
);
int
clearance
=
GetClearance
(
obs
.
m_
item
,
&
aLine
);
SHAPE_LINE_CHAIN
hull
=
obs
.
item
->
Hull
(
clearance
,
aItem
->
Width
()
);
SHAPE_LINE_CHAIN
hull
=
obs
.
m_
item
->
Hull
(
clearance
,
aItem
->
Width
()
);
if
(
aLine
.
EndsWithVia
()
)
{
int
clearance
=
GetClearance
(
obs
.
item
,
&
aLine
.
Via
()
);
int
clearance
=
GetClearance
(
obs
.
m_
item
,
&
aLine
.
Via
()
);
SHAPE_LINE_CHAIN
viaHull
=
aLine
.
Via
().
Hull
(
clearance
,
aItem
->
Width
()
);
...
...
@@ -313,13 +312,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
int
dist
=
aLine
.
CLine
().
Length
()
+
(
isect
.
p
-
aLine
.
Via
().
Pos
()
).
EuclideanNorm
();
if
(
dist
<
nearest
.
dist_f
irst
)
if
(
dist
<
nearest
.
m_distF
irst
)
{
found_isects
=
true
;
nearest
.
dist_f
irst
=
dist
;
nearest
.
ip_f
irst
=
isect
.
p
;
nearest
.
item
=
obs
.
item
;
nearest
.
hull
=
hull
;
nearest
.
m_distF
irst
=
dist
;
nearest
.
m_ipF
irst
=
isect
.
p
;
nearest
.
m_item
=
obs
.
m_
item
;
nearest
.
m_
hull
=
hull
;
}
if
(
dist
>
dist_max
)
...
...
@@ -338,13 +337,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
{
int
dist
=
aLine
.
CLine
().
PathLength
(
isect
.
p
);
if
(
dist
<
nearest
.
dist_f
irst
)
if
(
dist
<
nearest
.
m_distF
irst
)
{
found_isects
=
true
;
nearest
.
dist_f
irst
=
dist
;
nearest
.
ip_f
irst
=
isect
.
p
;
nearest
.
item
=
obs
.
item
;
nearest
.
hull
=
hull
;
nearest
.
m_distF
irst
=
dist
;
nearest
.
m_ipF
irst
=
isect
.
p
;
nearest
.
m_item
=
obs
.
m_
item
;
nearest
.
m_
hull
=
hull
;
}
if
(
dist
>
dist_max
)
...
...
@@ -354,37 +353,41 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
}
}
nearest
.
ip_l
ast
=
ip_last
;
nearest
.
dist_l
ast
=
dist_max
;
nearest
.
m_ipL
ast
=
ip_last
;
nearest
.
m_distL
ast
=
dist_max
;
}
if
(
!
found_isects
)
nearest
.
item
=
obs_list
[
0
].
item
;
if
(
!
found_isects
)
nearest
.
m_item
=
obs_list
[
0
].
m_
item
;
return
nearest
;
}
PNS_NODE
::
OptObstacle
PNS_NODE
::
CheckColliding
(
const
PNS_ITEMSET
&
aSet
,
int
aKindMask
)
PNS_NODE
::
OPT_OBSTACLE
PNS_NODE
::
CheckColliding
(
const
PNS_ITEMSET
&
aSet
,
int
aKindMask
)
{
BOOST_FOREACH
(
const
PNS_ITEM
*
item
,
aSet
.
CItems
()
)
BOOST_FOREACH
(
const
PNS_ITEM
*
item
,
aSet
.
CItems
()
)
{
OptObstacle
obs
=
CheckColliding
(
item
,
aKindMask
);
if
(
obs
)
OPT_OBSTACLE
obs
=
CheckColliding
(
item
,
aKindMask
);
if
(
obs
)
return
obs
;
}
return
OptObstacle
();
return
OPT_OBSTACLE
();
}
PNS_NODE
::
OptObstacle
PNS_NODE
::
CheckColliding
(
const
PNS_ITEM
*
aItemA
,
int
aKindMask
)
PNS_NODE
::
OPT_OBSTACLE
PNS_NODE
::
CheckColliding
(
const
PNS_ITEM
*
aItemA
,
int
aKindMask
)
{
O
bstacles
obs
;
O
BSTACLES
obs
;
obs
.
reserve
(
100
);
if
(
aItemA
->
Kind
()
==
PNS_ITEM
::
LINE
)
{
int
n
=
0
;
const
PNS_LINE
*
line
=
static_cast
<
const
PNS_LINE
*>
(
aItemA
);
const
PNS_LINE
*
line
=
static_cast
<
const
PNS_LINE
*>
(
aItemA
);
const
SHAPE_LINE_CHAIN
&
l
=
line
->
CLine
();
for
(
int
i
=
0
;
i
<
l
.
SegmentCount
();
i
++
)
...
...
@@ -393,7 +396,7 @@ PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKin
n
+=
QueryColliding
(
&
s
,
obs
,
aKindMask
,
1
);
if
(
n
)
return
O
ptObstacle
(
obs
[
0
]
);
return
O
PT_OBSTACLE
(
obs
[
0
]
);
}
if
(
line
->
EndsWithVia
()
)
...
...
@@ -401,13 +404,13 @@ PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKin
n
+=
QueryColliding
(
&
line
->
Via
(),
obs
,
aKindMask
,
1
);
if
(
n
)
return
O
ptObstacle
(
obs
[
0
]
);
return
O
PT_OBSTACLE
(
obs
[
0
]
);
}
}
else
if
(
QueryColliding
(
aItemA
,
obs
,
aKindMask
,
1
)
>
0
)
return
O
ptObstacle
(
obs
[
0
]
);
return
O
PT_OBSTACLE
(
obs
[
0
]
);
return
O
ptObstacle
();
return
O
PT_OBSTACLE
();
}
...
...
@@ -417,23 +420,24 @@ bool PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB, i
int
clearance
=
GetClearance
(
aItemA
,
aItemB
);
// fixme: refactor
if
(
aItemA
->
Kind
()
==
PNS_ITEM
::
LINE
)
clearance
+=
static_cast
<
const
PNS_LINE
*>
(
aItemA
)
->
Width
()
/
2
;
if
(
aItemB
->
Kind
()
==
PNS_ITEM
::
LINE
)
clearance
+=
static_cast
<
const
PNS_LINE
*>
(
aItemB
)
->
Width
()
/
2
;
if
(
aItemA
->
Kind
()
==
PNS_ITEM
::
LINE
)
clearance
+=
static_cast
<
const
PNS_LINE
*>
(
aItemA
)
->
Width
()
/
2
;
if
(
aItemB
->
Kind
()
==
PNS_ITEM
::
LINE
)
clearance
+=
static_cast
<
const
PNS_LINE
*>
(
aItemB
)
->
Width
()
/
2
;
return
aItemA
->
Collide
(
aItemB
,
clearance
);
}
struct
hitVisitor
struct
HIT_VISITOR
{
PNS_ITEMSET
&
m_items
;
const
VECTOR2I
&
m_point
;
const
PNS_NODE
*
m_world
;
hitVisitor
(
PNS_ITEMSET
&
aTab
,
const
VECTOR2I
&
aPoint
,
const
PNS_NODE
*
aWorld
)
:
m_items
(
aTab
),
m_point
(
aPoint
),
m_world
(
aWorld
)
{};
HIT_VISITOR
(
PNS_ITEMSET
&
aTab
,
const
VECTOR2I
&
aPoint
,
const
PNS_NODE
*
aWorld
)
:
m_items
(
aTab
),
m_point
(
aPoint
),
m_world
(
aWorld
)
{}
bool
operator
()(
PNS_ITEM
*
aItem
)
{
...
...
@@ -455,17 +459,17 @@ const PNS_ITEMSET PNS_NODE::HitTest( const VECTOR2I& aPoint ) const
// fixme: we treat a point as an infinitely small circle - this is inefficient.
SHAPE_CIRCLE
s
(
aPoint
,
0
);
hitVisitor
visitor
(
items
,
aPoint
,
this
);
HIT_VISITOR
visitor
(
items
,
aPoint
,
this
);
m_index
->
Query
(
&
s
,
m_maxClearance
,
visitor
);
if
(
!
isRoot
()
)
// fixme: could be made cleaner
{
PNS_ITEMSET
items_root
;
hitVisitor
visitor_root
(
items_root
,
aPoint
,
m_root
);
HIT_VISITOR
visitor_root
(
items_root
,
aPoint
,
m_root
);
m_root
->
m_index
->
Query
(
&
s
,
m_maxClearance
,
visitor_root
);
BOOST_FOREACH
(
PNS_ITEM
*
item
,
items_root
.
Items
()
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
items_root
.
Items
()
)
{
if
(
!
overrides
(
item
)
)
items
.
Add
(
item
);
...
...
@@ -506,10 +510,10 @@ void PNS_NODE::addLine( PNS_LINE* aLine, bool aAllowRedundant )
if
(
!
aAllowRedundant
)
psegR
=
findRedundantSegment
(
pseg
);
if
(
psegR
)
aLine
->
LinkSegment
(
psegR
);
else
{
if
(
psegR
)
aLine
->
LinkSegment
(
psegR
);
else
{
pseg
->
SetOwner
(
this
);
linkJoint
(
s
.
A
,
pseg
->
Layers
(),
aLine
->
Net
(),
pseg
);
...
...
@@ -532,7 +536,7 @@ void PNS_NODE::addSegment( PNS_SEGMENT* aSeg, bool aAllowRedundant )
return
;
}
if
(
!
aAllowRedundant
&&
findRedundantSegment
(
aSeg
)
)
if
(
!
aAllowRedundant
&&
findRedundantSegment
(
aSeg
)
)
return
;
aSeg
->
SetOwner
(
this
);
...
...
@@ -559,11 +563,11 @@ void PNS_NODE::Add( PNS_ITEM* aItem, bool aAllowRedundant )
break
;
case
PNS_ITEM
:
:
LINE
:
addLine
(
static_cast
<
PNS_LINE
*>
(
aItem
),
aAllowRedundant
);
addLine
(
static_cast
<
PNS_LINE
*>
(
aItem
),
aAllowRedundant
);
break
;
case
PNS_ITEM
:
:
VIA
:
addVia
(
static_cast
<
PNS_VIA
*>
(
aItem
)
);
addVia
(
static_cast
<
PNS_VIA
*>
(
aItem
)
);
break
;
default
:
...
...
@@ -574,7 +578,6 @@ void PNS_NODE::Add( PNS_ITEM* aItem, bool aAllowRedundant )
void
PNS_NODE
::
doRemove
(
PNS_ITEM
*
aItem
)
{
// assert(m_root->m_index->Contains(aItem) || m_index->Contains(aItem));
// case 1: removing an item that is stored in the root node from any branch:
...
...
@@ -612,7 +615,7 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
assert
(
segRefs
!=
NULL
);
assert
(
aLine
->
Owner
());
if
(
(
int
)
segRefs
->
size
()
!=
aLine
->
SegmentCount
())
if
(
(
int
)
segRefs
->
size
()
!=
aLine
->
SegmentCount
()
)
{
//printf("******weird deletion: segrefs %d segcount %d hasloops %d\n", segRefs->size(), aLine->SegmentCount(), aLine->HasLoops());
}
...
...
@@ -627,20 +630,19 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
}
void
PNS_NODE
::
removeVia
(
PNS_VIA
*
aVia
)
{
// We have to split a single joint (associated with a via, binding together multiple layers)
// into multiple independent joints. As I'm a lazy bastard, I simply delete the via and all its links and re-insert them.
PNS_JOINT
::
H
ashTag
tag
;
PNS_JOINT
::
H
ASH_TAG
tag
;
VECTOR2I
p
(
aVia
->
Pos
()
);
PNS_LAYERSET
vLayers
(
aVia
->
Layers
()
);
VECTOR2I
p
(
aVia
->
Pos
()
);
PNS_LAYERSET
vLayers
(
aVia
->
Layers
()
);
int
net
=
aVia
->
Net
();
PNS_JOINT
*
jt
=
FindJoint
(
p
,
vLayers
.
Start
(),
net
);
PNS_JOINT
::
L
inkedItems
links
(
jt
->
LinkList
()
);
PNS_JOINT
*
jt
=
FindJoint
(
p
,
vLayers
.
Start
(),
net
);
PNS_JOINT
::
L
INKED_ITEMS
links
(
jt
->
LinkList
()
);
tag
.
net
=
net
;
tag
.
pos
=
p
;
...
...
@@ -649,14 +651,14 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
do
{
split
=
false
;
std
::
pair
<
J
ointMap
::
iterator
,
JointMap
::
iterator
>
range
=
m_joints
.
equal_range
(
tag
);
std
::
pair
<
J
OINT_MAP
::
iterator
,
JOINT_MAP
::
iterator
>
range
=
m_joints
.
equal_range
(
tag
);
if
(
range
.
first
==
m_joints
.
end
()
)
break
;
// find and remove all joints containing the via to be removed
for
(
J
ointMap
::
iterator
f
=
range
.
first
;
f
!=
range
.
second
;
++
f
)
for
(
J
OINT_MAP
::
iterator
f
=
range
.
first
;
f
!=
range
.
second
;
++
f
)
{
if
(
aVia
->
LayersOverlap
(
&
f
->
second
)
)
{
...
...
@@ -665,10 +667,10 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
break
;
}
}
}
while
(
split
);
}
while
(
split
);
// and re-link them, using the former via's link list
BOOST_FOREACH
(
PNS_ITEM
*
item
,
links
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
links
)
{
if
(
item
!=
aVia
)
linkJoint
(
p
,
item
->
Layers
(),
net
,
item
);
...
...
@@ -677,6 +679,7 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
doRemove
(
aVia
);
}
void
PNS_NODE
::
Replace
(
PNS_ITEM
*
aOldItem
,
PNS_ITEM
*
aNewItem
)
{
Remove
(
aOldItem
);
...
...
@@ -711,37 +714,37 @@ void PNS_NODE::Remove( PNS_ITEM* aItem )
}
void
PNS_NODE
::
followLine
(
PNS_SEGMENT
*
current
,
bool
scanDirection
,
int
&
p
os
,
int
limit
,
VECTOR2I
*
corners
,
PNS_SEGMENT
**
s
egments
)
void
PNS_NODE
::
followLine
(
PNS_SEGMENT
*
aCurrent
,
bool
aScanDirection
,
int
&
aP
os
,
int
aLimit
,
VECTOR2I
*
aCorners
,
PNS_SEGMENT
**
aS
egments
)
{
bool
prevReversed
=
false
;
for
(
;
;
)
{
const
VECTOR2I
p
=
(
scanDirection
^
prevReversed
)
?
current
->
Seg
().
B
:
c
urrent
->
Seg
().
A
;
const
PNS_JOINT
*
jt
=
FindJoint
(
p
,
current
);
(
aScanDirection
^
prevReversed
)
?
aCurrent
->
Seg
().
B
:
aC
urrent
->
Seg
().
A
;
const
PNS_JOINT
*
jt
=
FindJoint
(
p
,
aCurrent
);
assert
(
jt
);
assert
(
pos
>
0
&&
pos
<
l
imit
);
assert
(
aPos
>
0
&&
aPos
<
aL
imit
);
corners
[
p
os
]
=
jt
->
Pos
();
segments
[
pos
]
=
c
urrent
;
aCorners
[
aP
os
]
=
jt
->
Pos
();
aSegments
[
aPos
]
=
aC
urrent
;
pos
+=
(
scanDirection
?
1
:
-
1
);
aPos
+=
(
aScanDirection
?
1
:
-
1
);
if
(
!
jt
->
IsLineCorner
()
)
break
;
current
=
jt
->
NextSegment
(
c
urrent
);
aCurrent
=
jt
->
NextSegment
(
aC
urrent
);
prevReversed
=
(
jt
->
Pos
()
==
(
scanDirection
?
current
->
Seg
().
B
:
c
urrent
->
Seg
().
A
)
);
(
jt
->
Pos
()
==
(
aScanDirection
?
aCurrent
->
Seg
().
B
:
aC
urrent
->
Seg
().
A
)
);
}
}
PNS_LINE
*
PNS_NODE
::
AssembleLine
(
PNS_SEGMENT
*
aSeg
,
int
*
aOriginSegmentIndex
)
PNS_LINE
*
PNS_NODE
::
AssembleLine
(
PNS_SEGMENT
*
aSeg
,
int
*
aOriginSegmentIndex
)
{
const
int
MaxVerts
=
1024
;
...
...
@@ -761,7 +764,7 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex)
int
n
=
0
;
PNS_SEGMENT
*
prev_seg
=
NULL
;
PNS_SEGMENT
*
prev_seg
=
NULL
;
for
(
int
i
=
i_start
+
1
;
i
<
i_end
;
i
++
)
{
...
...
@@ -773,8 +776,9 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex)
{
pl
->
LinkSegment
(
segs
[
i
]
);
if
(
segs
[
i
]
==
aSeg
&&
aOriginSegmentIndex
)
if
(
segs
[
i
]
==
aSeg
&&
aOriginSegmentIndex
)
*
aOriginSegmentIndex
=
n
;
n
++
;
}
...
...
@@ -782,53 +786,57 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex)
}
assert
(
pl
->
SegmentCount
()
!=
0
);
assert
(
pl
->
SegmentCount
()
==
(
int
)
pl
->
LinkedSegments
()
->
size
()
);
assert
(
pl
->
SegmentCount
()
!=
0
);
assert
(
pl
->
SegmentCount
()
==
(
int
)
pl
->
LinkedSegments
()
->
size
()
);
return
pl
;
}
void
PNS_NODE
::
FindLineEnds
(
PNS_LINE
*
aLine
,
PNS_JOINT
&
a
,
PNS_JOINT
&
b
)
void
PNS_NODE
::
FindLineEnds
(
PNS_LINE
*
aLine
,
PNS_JOINT
&
a
A
,
PNS_JOINT
&
aB
)
{
a
=
*
FindJoint
(
aLine
->
CPoint
(
0
),
aLine
);
b
=
*
FindJoint
(
aLine
->
CPoint
(
-
1
),
aLine
);
a
A
=
*
FindJoint
(
aLine
->
CPoint
(
0
),
aLine
);
aB
=
*
FindJoint
(
aLine
->
CPoint
(
-
1
),
aLine
);
}
void
PNS_NODE
::
MapConnectivity
(
PNS_JOINT
*
aStart
,
std
::
vector
<
PNS_JOINT
*>
&
aFoundJoints
)
void
PNS_NODE
::
MapConnectivity
(
PNS_JOINT
*
aStart
,
std
::
vector
<
PNS_JOINT
*>&
aFoundJoints
)
{
std
::
deque
<
PNS_JOINT
*>
searchQueue
;
std
::
set
<
PNS_JOINT
*>
processed
;
searchQueue
.
push_back
(
aStart
);
processed
.
insert
(
aStart
);
searchQueue
.
push_back
(
aStart
);
processed
.
insert
(
aStart
);
while
(
!
searchQueue
.
empty
()
)
while
(
!
searchQueue
.
empty
()
)
{
PNS_JOINT
*
current
=
searchQueue
.
front
();
PNS_JOINT
*
current
=
searchQueue
.
front
();
searchQueue
.
pop_front
();
BOOST_FOREACH
(
PNS_ITEM
*
item
,
current
->
LinkList
()
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
current
->
LinkList
()
)
{
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
)
{
PNS_SEGMENT
*
seg
=
static_cast
<
PNS_SEGMENT
*>
(
item
);
PNS_JOINT
*
a
=
FindJoint
(
seg
->
Seg
().
A
,
seg
);
PNS_JOINT
*
b
=
FindJoint
(
seg
->
Seg
().
B
,
seg
);
PNS_JOINT
*
next
=
(
*
a
==
*
current
)
?
b
:
a
;
PNS_SEGMENT
*
seg
=
static_cast
<
PNS_SEGMENT
*>
(
item
);
PNS_JOINT
*
a
=
FindJoint
(
seg
->
Seg
().
A
,
seg
);
PNS_JOINT
*
b
=
FindJoint
(
seg
->
Seg
().
B
,
seg
);
PNS_JOINT
*
next
=
(
*
a
==
*
current
)
?
b
:
a
;
if
(
processed
.
find
(
next
)
==
processed
.
end
()
)
{
processed
.
insert
(
next
);
processed
.
insert
(
next
);
searchQueue
.
push_back
(
next
);
}
}
}
}
BOOST_FOREACH
(
PNS_JOINT
*
jt
,
processed
)
BOOST_FOREACH
(
PNS_JOINT
*
jt
,
processed
)
aFoundJoints
.
push_back
(
jt
);
}
PNS_ITEM
*
PNS_NODE
::
NearestUnconnectedItem
(
PNS_JOINT
*
aStart
,
int
*
aAnchor
,
int
aKindMask
)
PNS_ITEM
*
PNS_NODE
::
NearestUnconnectedItem
(
PNS_JOINT
*
aStart
,
int
*
aAnchor
,
int
aKindMask
)
{
std
::
set
<
PNS_ITEM
*>
disconnected
;
std
::
vector
<
PNS_JOINT
*>
joints
;
...
...
@@ -836,32 +844,33 @@ PNS_ITEM *PNS_NODE::NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor, in
AllItemsInNet
(
aStart
->
Net
(),
disconnected
);
MapConnectivity
(
aStart
,
joints
);
BOOST_FOREACH
(
PNS_JOINT
*
jt
,
joints
)
BOOST_FOREACH
(
PNS_JOINT
*
jt
,
joints
)
{
BOOST_FOREACH
(
PNS_ITEM
*
link
,
jt
->
LinkList
()
)
BOOST_FOREACH
(
PNS_ITEM
*
link
,
jt
->
LinkList
()
)
{
if
(
disconnected
.
find
(
link
)
!=
disconnected
.
end
()
)
disconnected
.
erase
(
link
);
if
(
disconnected
.
find
(
link
)
!=
disconnected
.
end
()
)
disconnected
.
erase
(
link
);
}
}
int
best_dist
=
INT_MAX
;
PNS_ITEM
*
best
=
NULL
;
PNS_ITEM
*
best
=
NULL
;
BOOST_FOREACH
(
PNS_ITEM
*
item
,
disconnected
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
disconnected
)
{
if
(
item
->
OfKind
(
aKindMask
)
)
if
(
item
->
OfKind
(
aKindMask
)
)
{
for
(
int
i
=
0
;
i
<
item
->
AnchorCount
();
i
++
)
{
VECTOR2I
p
=
item
->
Anchor
(
i
);
int
d
=
(
p
-
aStart
->
Pos
()
).
EuclideanNorm
();
VECTOR2I
p
=
item
->
Anchor
(
i
);
int
d
=
(
p
-
aStart
->
Pos
()
).
EuclideanNorm
();
if
(
d
<
best_dist
)
if
(
d
<
best_dist
)
{
best_dist
=
d
;
best
=
item
;
if
(
aAnchor
)
if
(
aAnchor
)
*
aAnchor
=
i
;
}
}
...
...
@@ -871,31 +880,32 @@ PNS_ITEM *PNS_NODE::NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor, in
return
best
;
}
int
PNS_NODE
::
FindLinesBetweenJoints
(
PNS_JOINT
&
a
,
PNS_JOINT
&
b
,
std
::
vector
<
PNS_LINE
*>&
aLines
)
int
PNS_NODE
::
FindLinesBetweenJoints
(
PNS_JOINT
&
aA
,
PNS_JOINT
&
aB
,
std
::
vector
<
PNS_LINE
*>&
aLines
)
{
BOOST_FOREACH
(
PNS_ITEM
*
item
,
a
.
LinkList
()
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
a
A
.
LinkList
()
)
{
if
(
item
->
Kind
()
==
PNS_ITEM
::
SEGMENT
)
{
PNS_SEGMENT
*
seg
=
static_cast
<
PNS_SEGMENT
*>
(
item
);
PNS_SEGMENT
*
seg
=
static_cast
<
PNS_SEGMENT
*>
(
item
);
PNS_LINE
*
line
=
AssembleLine
(
seg
);
PNS_JOINT
j_start
,
j_end
;
FindLineEnds
(
line
,
j_start
,
j_end
);
int
id_start
=
line
->
CLine
().
Find
(
aA
.
Pos
()
);
int
id_end
=
line
->
CLine
().
Find
(
aB
.
Pos
()
);
i
nt
id_start
=
line
->
CLine
().
Find
(
a
.
Pos
());
int
id_end
=
line
->
CLine
().
Find
(
b
.
Pos
()
);
i
f
(
id_end
<
id_start
)
std
::
swap
(
id_end
,
id_start
);
if
(
id_end
<
id_start
)
std
::
swap
(
id_end
,
id_start
);
if
(
id_start
>=
0
&&
id_end
>=
0
)
if
(
id_start
>=
0
&&
id_end
>=
0
)
{
line
->
ClipVertexRange
(
id_start
,
id_end
);
aLines
.
push_back
(
line
);
}
else
}
else
delete
line
;
}
}
...
...
@@ -906,12 +916,12 @@ int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& a, PNS_JOINT& b, std::vector<PN
PNS_JOINT
*
PNS_NODE
::
FindJoint
(
const
VECTOR2I
&
aPos
,
int
aLayer
,
int
aNet
)
{
PNS_JOINT
::
H
ashTag
tag
;
PNS_JOINT
::
H
ASH_TAG
tag
;
tag
.
net
=
aNet
;
tag
.
pos
=
aPos
;
J
ointMap
::
iterator
f
=
m_joints
.
find
(
tag
),
end
=
m_joints
.
end
();
J
OINT_MAP
::
iterator
f
=
m_joints
.
find
(
tag
),
end
=
m_joints
.
end
();
if
(
f
==
end
&&
!
isRoot
()
)
{
...
...
@@ -936,15 +946,15 @@ PNS_JOINT* PNS_NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet )
PNS_JOINT
&
PNS_NODE
::
touchJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
)
{
PNS_JOINT
::
H
ashTag
tag
;
PNS_JOINT
::
H
ASH_TAG
tag
;
tag
.
pos
=
aPos
;
tag
.
net
=
aNet
;
// try to find the joint in this node.
J
ointMap
::
iterator
f
=
m_joints
.
find
(
tag
);
J
OINT_MAP
::
iterator
f
=
m_joints
.
find
(
tag
);
std
::
pair
<
J
ointMap
::
iterator
,
JointMap
::
iterator
>
range
;
std
::
pair
<
J
OINT_MAP
::
iterator
,
JOINT_MAP
::
iterator
>
range
;
// not found and we are not root? find in the root and copy results here.
if
(
f
==
m_joints
.
end
()
&&
!
isRoot
()
)
...
...
@@ -978,7 +988,8 @@ PNS_JOINT& PNS_NODE::touchJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLaye
break
;
}
}
}
while
(
merged
);
}
while
(
merged
);
return
m_joints
.
insert
(
TagJointPair
(
tag
,
jt
)
)
->
second
;
}
...
...
@@ -991,10 +1002,8 @@ void PNS_JOINT::Dump() const
}
void
PNS_NODE
::
linkJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
,
PNS_ITEM
*
aWhere
)
void
PNS_NODE
::
linkJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
,
PNS_ITEM
*
aWhere
)
{
PNS_JOINT
&
jt
=
touchJoint
(
aPos
,
aLayers
,
aNet
);
...
...
@@ -1021,7 +1030,7 @@ void PNS_NODE::Dump( bool aLong )
for( i = m_items.begin(); i != m_items.end(); i++ )
{
if( (*i)->GetKind() == PNS_ITEM::SEGMENT )
all_segs.insert( static_cast<PNS_SEGMENT*>(
*i
) );
all_segs.insert( static_cast<PNS_SEGMENT*>(
*i
) );
}
if( !isRoot() )
...
...
@@ -1033,24 +1042,24 @@ void PNS_NODE::Dump( bool aLong )
}
}
J
ointMap
::iterator j;
J
OINT_MAP
::iterator j;
if( aLong )
for( j = m_joints.begin(); j
!=
m_joints.end(); ++j )
for( j = m_joints.begin(); j
!=
m_joints.end(); ++j )
{
printf( "joint : %s, links : %d\n",
j->second.GetPos().Format().c_str(), j->second.LinkCount() );
PNS_JOINT::L
inkedItems
::const_iterator k;
PNS_JOINT::L
INKED_ITEMS
::const_iterator k;
for( k = j->second.GetLinkList().begin(); k != j->second.GetLinkList().end(); ++k )
{
const PNS_ITEM* item = *k;
const PNS_ITEM*
m_
item = *k;
switch( item->GetKind() )
switch(
m_
item->GetKind() )
{
case PNS_ITEM::SEGMENT:
{
const PNS_SEGMENT* seg = static_cast<const PNS_SEGMENT*>(
item
);
const PNS_SEGMENT* seg = static_cast<const PNS_SEGMENT*>(
m_item
);
printf( " -> seg %s %s\n", seg->GetSeg().A.Format().c_str(),
seg->GetSeg().B.Format().c_str() );
break;
...
...
@@ -1075,7 +1084,6 @@ void PNS_NODE::Dump( bool aLong )
if( aLong )
printf( "Line: %s, net %d ", l->GetLine().Format().c_str(), l->GetNet() );
for( std::vector<PNS_SEGMENT*>::iterator j = seg_refs->begin(); j != seg_refs->end(); ++j )
{
printf( "%s ", (*j)->GetSeg().A.Format().c_str() );
...
...
@@ -1094,7 +1102,7 @@ void PNS_NODE::Dump( bool aLong )
}
void
PNS_NODE
::
GetUpdatedItems
(
I
temVector
&
aRemoved
,
ItemVector
&
aAdded
)
void
PNS_NODE
::
GetUpdatedItems
(
I
TEM_VECTOR
&
aRemoved
,
ITEM_VECTOR
&
aAdded
)
{
aRemoved
.
reserve
(
m_override
.
size
()
);
aAdded
.
reserve
(
m_index
->
Size
()
);
...
...
@@ -1102,10 +1110,10 @@ void PNS_NODE::GetUpdatedItems( ItemVector& aRemoved, ItemVector& aAdded )
if
(
isRoot
()
)
return
;
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_override
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_override
)
aRemoved
.
push_back
(
item
);
for
(
PNS_INDEX
::
I
temSet
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
for
(
PNS_INDEX
::
I
TEM_SET
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
aAdded
.
push_back
(
*
i
);
}
...
...
@@ -1115,7 +1123,8 @@ void PNS_NODE::releaseChildren()
// copy the kids as the PNS_NODE destructor erases the item from the parent node.
std
::
vector
<
PNS_NODE
*>
kids
=
m_children
;
BOOST_FOREACH
(
PNS_NODE
*
node
,
kids
)
{
BOOST_FOREACH
(
PNS_NODE
*
node
,
kids
)
{
node
->
releaseChildren
();
delete
node
;
}
...
...
@@ -1130,11 +1139,11 @@ void PNS_NODE::Commit( PNS_NODE* aNode )
BOOST_FOREACH
(
PNS_ITEM
*
item
,
aNode
->
m_override
)
Remove
(
item
);
for
(
PNS_INDEX
::
I
temSet
::
iterator
i
=
aNode
->
m_index
->
begin
();
for
(
PNS_INDEX
::
I
TEM_SET
::
iterator
i
=
aNode
->
m_index
->
begin
();
i
!=
aNode
->
m_index
->
end
();
++
i
)
{
(
*
i
)
->
SetRank
(
-
1
);
(
*
i
)
->
Unmark
();
(
*
i
)
->
SetRank
(
-
1
);
(
*
i
)
->
Unmark
();
Add
(
*
i
);
}
...
...
@@ -1151,74 +1160,86 @@ void PNS_NODE::KillChildren()
void
PNS_NODE
::
AllItemsInNet
(
int
aNet
,
std
::
set
<
PNS_ITEM
*>&
aItems
)
{
PNS_INDEX
::
NetItemsList
*
l_cur
=
m_index
->
GetItemsForNet
(
aNet
);
PNS_INDEX
::
NET_ITEMS_LIST
*
l_cur
=
m_index
->
GetItemsForNet
(
aNet
);
if
(
l_cur
)
if
(
l_cur
)
{
BOOST_FOREACH
(
PNS_ITEM
*
item
,
*
l_cur
)
aItems
.
insert
(
item
);
BOOST_FOREACH
(
PNS_ITEM
*
item
,
*
l_cur
)
aItems
.
insert
(
item
);
}
if
(
!
isRoot
()
)
{
PNS_INDEX
::
N
etItemsList
*
l_root
=
m_root
->
m_index
->
GetItemsForNet
(
aNet
);
PNS_INDEX
::
N
ET_ITEMS_LIST
*
l_root
=
m_root
->
m_index
->
GetItemsForNet
(
aNet
);
if
(
l_root
)
for
(
PNS_INDEX
::
N
etItemsList
::
iterator
i
=
l_root
->
begin
();
i
!=
l_root
->
end
();
++
i
)
if
(
l_root
)
for
(
PNS_INDEX
::
N
ET_ITEMS_LIST
::
iterator
i
=
l_root
->
begin
();
i
!=
l_root
->
end
();
++
i
)
if
(
!
overrides
(
*
i
)
)
aItems
.
insert
(
*
i
);
}
}
void
PNS_NODE
::
ClearRanks
()
{
for
(
PNS_INDEX
::
I
temSet
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
for
(
PNS_INDEX
::
I
TEM_SET
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
{
(
*
i
)
->
SetRank
(
-
1
);
(
*
i
)
->
Mark
(
0
);
(
*
i
)
->
SetRank
(
-
1
);
(
*
i
)
->
Mark
(
0
);
}
}
int
PNS_NODE
::
FindByMarker
(
int
aMarker
,
PNS_ITEMSET
&
aItems
)
int
PNS_NODE
::
FindByMarker
(
int
aMarker
,
PNS_ITEMSET
&
aItems
)
{
for
(
PNS_INDEX
::
ItemSet
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
if
(
(
*
i
)
->
Marker
()
&
aMarker
)
aItems
.
Add
(
*
i
);
for
(
PNS_INDEX
::
ITEM_SET
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
{
if
(
(
*
i
)
->
Marker
()
&
aMarker
)
aItems
.
Add
(
*
i
);
}
return
0
;
}
int
PNS_NODE
::
RemoveByMarker
(
int
aMarker
)
int
PNS_NODE
::
RemoveByMarker
(
int
aMarker
)
{
for
(
PNS_INDEX
::
ItemSet
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
for
(
PNS_INDEX
::
ITEM_SET
::
iterator
i
=
m_index
->
begin
();
i
!=
m_index
->
end
();
++
i
)
{
if
(
(
*
i
)
->
Marker
()
&
aMarker
)
{
Remove
(
*
i
);
Remove
(
*
i
);
}
}
return
0
;
}
PNS_SEGMENT
*
PNS_NODE
::
findRedundantSegment
(
PNS_SEGMENT
*
aSeg
)
{
PNS_JOINT
*
jtStart
=
FindJoint
(
aSeg
->
Seg
().
A
,
aSeg
);
PNS_JOINT
*
jtStart
=
FindJoint
(
aSeg
->
Seg
().
A
,
aSeg
);
if
(
!
jtStart
)
if
(
!
jtStart
)
return
NULL
;
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jtStart
->
LinkList
()
)
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
))
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jtStart
->
LinkList
()
)
{
PNS_SEGMENT
*
seg2
=
(
PNS_SEGMENT
*
)
item
;
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
)
{
PNS_SEGMENT
*
seg2
=
(
PNS_SEGMENT
*
)
item
;
const
VECTOR2I
a1
(
aSeg
->
Seg
().
A
);
const
VECTOR2I
b1
(
aSeg
->
Seg
().
B
);
const
VECTOR2I
a1
(
aSeg
->
Seg
().
A
);
const
VECTOR2I
b1
(
aSeg
->
Seg
().
B
);
const
VECTOR2I
a2
(
seg2
->
Seg
().
A
);
const
VECTOR2I
b2
(
seg2
->
Seg
().
B
);
const
VECTOR2I
a2
(
seg2
->
Seg
().
A
);
const
VECTOR2I
b2
(
seg2
->
Seg
().
B
);
if
(
seg2
->
Layers
().
Start
()
==
aSeg
->
Layers
().
Start
()
&&
(
(
a1
==
a2
&&
b1
==
b2
)
||
(
a1
==
b2
&&
a2
==
b1
))
)
(
(
a1
==
a2
&&
b1
==
b2
)
||
(
a1
==
b2
&&
a2
==
b1
)
)
)
return
seg2
;
}
}
return
NULL
;
}
pcbnew/router/pns_node.h
View file @
ad1b138f
...
...
@@ -52,7 +52,7 @@ class PNS_INDEX;
class
PNS_CLEARANCE_FUNC
{
public
:
virtual
int
operator
()(
const
PNS_ITEM
*
a
,
const
PNS_ITEM
*
b
)
=
0
;
virtual
int
operator
()(
const
PNS_ITEM
*
a
A
,
const
PNS_ITEM
*
aB
)
=
0
;
virtual
~
PNS_CLEARANCE_FUNC
()
{}
};
...
...
@@ -65,20 +65,20 @@ public:
struct
PNS_OBSTACLE
{
///> Item we search collisions with
PNS_ITEM
*
head
;
PNS_ITEM
*
m_
head
;
///> Item found to be colliding with head
PNS_ITEM
*
item
;
///> Item found to be colliding with
m_
head
PNS_ITEM
*
m_
item
;
///> Hull of the colliding item
SHAPE_LINE_CHAIN
hull
;
///> Hull of the colliding
m_
item
SHAPE_LINE_CHAIN
m_
hull
;
///> First and last intersection point between the head item and the hull
///> of the colliding item
VECTOR2I
ip_first
,
ip_l
ast
;
///> of the colliding
m_
item
VECTOR2I
m_ipFirst
,
m_ipL
ast
;
///> ... and the distance thereof
int
dist_first
,
dist_l
ast
;
int
m_distFirst
,
m_distL
ast
;
};
/**
...
...
@@ -93,34 +93,33 @@ struct PNS_OBSTACLE
* - lightweight cloning/branching (for recursive optimization and shove
* springback)
**/
class
PNS_NODE
{
public
:
typedef
boost
::
optional
<
PNS_OBSTACLE
>
O
ptObstacle
;
typedef
std
::
vector
<
PNS_ITEM
*>
I
temVector
;
typedef
std
::
vector
<
PNS_OBSTACLE
>
O
bstacles
;
typedef
boost
::
optional
<
PNS_OBSTACLE
>
O
PT_OBSTACLE
;
typedef
std
::
vector
<
PNS_ITEM
*>
I
TEM_VECTOR
;
typedef
std
::
vector
<
PNS_OBSTACLE
>
O
BSTACLES
;
PNS_NODE
();
~
PNS_NODE
();
///> Returns the expected clearance between items a and b.
int
GetClearance
(
const
PNS_ITEM
*
a
,
const
PNS_ITEM
*
b
)
const
;
int
GetClearance
(
const
PNS_ITEM
*
aA
,
const
PNS_ITEM
*
aB
)
const
;
///> Returns the pre-set worst case clearance between any pair of items
int
GetMaxClearance
()
const
int
GetMaxClearance
()
const
{
return
m_maxClearance
;
}
///> Sets the worst-case clerance between any pair of items
void
SetMaxClearance
(
int
aClearance
)
void
SetMaxClearance
(
int
aClearance
)
{
m_maxClearance
=
aClearance
;
}
///> Assigns a clerance resolution function object
void
SetClearanceFunctor
(
PNS_CLEARANCE_FUNC
*
aFunc
)
void
SetClearanceFunctor
(
PNS_CLEARANCE_FUNC
*
aFunc
)
{
m_clearanceFunctor
=
aFunc
;
}
...
...
@@ -147,12 +146,11 @@ public:
* @param aLimitCount stop looking for collisions after finding this number of colliding items
* @return number of obstacles found
*/
int
QueryColliding
(
const
PNS_ITEM
*
aItem
,
Obstacles
&
aObstacles
,
int
QueryColliding
(
const
PNS_ITEM
*
aItem
,
OBSTACLES
&
aObstacles
,
int
aKindMask
=
PNS_ITEM
::
ANY
,
int
aLimitCount
=
-
1
);
/**
* Function NearestObstacle()
*
...
...
@@ -162,7 +160,7 @@ public:
* @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty.
*/
O
ptObstacle
NearestObstacle
(
const
PNS_LINE
*
aItem
,
O
PT_OBSTACLE
NearestObstacle
(
const
PNS_LINE
*
aItem
,
int
aKindMask
=
PNS_ITEM
::
ANY
);
/**
...
...
@@ -174,7 +172,7 @@ public:
* @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty.
*/
O
ptObstacle
CheckColliding
(
const
PNS_ITEM
*
aItem
,
O
PT_OBSTACLE
CheckColliding
(
const
PNS_ITEM
*
aItem
,
int
aKindMask
=
PNS_ITEM
::
ANY
);
...
...
@@ -187,7 +185,7 @@ public:
* @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty.
*/
O
ptObstacle
CheckColliding
(
const
PNS_ITEMSET
&
aSet
,
O
PT_OBSTACLE
CheckColliding
(
const
PNS_ITEMSET
&
aSet
,
int
aKindMask
=
PNS_ITEM
::
ANY
);
...
...
@@ -200,7 +198,7 @@ public:
* @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty.
*/
bool
CheckColliding
(
const
PNS_ITEM
*
aItemA
,
bool
CheckColliding
(
const
PNS_ITEM
*
aItemA
,
const
PNS_ITEM
*
aItemB
,
int
aKindMask
=
PNS_ITEM
::
ANY
);
...
...
@@ -211,7 +209,7 @@ public:
* @param aPoint the point
* @return the items
*/
const
PNS_ITEMSET
HitTest
(
const
VECTOR2I
&
aPoint
)
const
;
const
PNS_ITEMSET
HitTest
(
const
VECTOR2I
&
aPoint
)
const
;
/**
* Function Add()
...
...
@@ -221,7 +219,7 @@ public:
* @param aAllowRedundant if true, duplicate items are allowed (e.g. a segment or via
* at the same coordinates as an existing one)
*/
void
Add
(
PNS_ITEM
*
aItem
,
bool
aAllowRedundant
=
false
);
void
Add
(
PNS_ITEM
*
aItem
,
bool
aAllowRedundant
=
false
);
/**
* Function Remove()
...
...
@@ -229,7 +227,7 @@ public:
* Just as the name says, removes an item from this branch.
* @param aItem item to remove
*/
void
Remove
(
PNS_ITEM
*
aItem
);
void
Remove
(
PNS_ITEM
*
aItem
);
/**
* Function Replace()
...
...
@@ -238,7 +236,7 @@ public:
* @param aOldItem item to be removed
* @param aNewItem item add instead
*/
void
Replace
(
PNS_ITEM
*
aOldItem
,
PNS_ITEM
*
aNewItem
);
void
Replace
(
PNS_ITEM
*
aOldItem
,
PNS_ITEM
*
aNewItem
);
/**
* Function Branch()
...
...
@@ -248,7 +246,7 @@ public:
* any branches in use, their parents must NOT be deleted.
* @return the new branch
*/
PNS_NODE
*
Branch
(
);
PNS_NODE
*
Branch
(
);
/**
* Function AssembleLine()
...
...
@@ -259,14 +257,10 @@ public:
* @param aOriginSegmentIndex index of aSeg in the resulting line
* @return the line
*/
PNS_LINE
*
AssembleLine
(
PNS_SEGMENT
*
aSeg
,
int
*
aOriginSegmentIndex
=
NULL
);
PNS_LINE
*
AssembleLine
(
PNS_SEGMENT
*
aSeg
,
int
*
aOriginSegmentIndex
=
NULL
);
///> Prints the contents and joints structure
void
Dump
(
bool
aLong
=
false
);
void
Dump
(
bool
aLong
=
false
);
/**
* Function GetUpdatedItems()
...
...
@@ -276,8 +270,7 @@ public:
* @param aRemoved removed items
* @param aAdded added items
*/
void
GetUpdatedItems
(
ItemVector
&
aRemoved
,
ItemVector
&
aAdded
);
void
GetUpdatedItems
(
ITEM_VECTOR
&
aRemoved
,
ITEM_VECTOR
&
aAdded
);
/**
* Function Commit()
...
...
@@ -302,23 +295,24 @@ public:
* Searches for a joint at a given position, linked to given item.
* @return the joint, if found, otherwise empty
*/
PNS_JOINT
*
FindJoint
(
const
VECTOR2I
&
aPos
,
PNS_ITEM
*
aItem
)
PNS_JOINT
*
FindJoint
(
const
VECTOR2I
&
aPos
,
PNS_ITEM
*
aItem
)
{
return
FindJoint
(
aPos
,
aItem
->
Layers
().
Start
(),
aItem
->
Net
()
);
}
void
MapConnectivity
(
PNS_JOINT
*
aStart
,
std
::
vector
<
PNS_JOINT
*>
&
aFoundJoints
);
void
MapConnectivity
(
PNS_JOINT
*
aStart
,
std
::
vector
<
PNS_JOINT
*>
&
aFoundJoints
);
PNS_ITEM
*
NearestUnconnectedItem
(
PNS_JOINT
*
aStart
,
int
*
aAnchor
=
NULL
,
int
aKindMask
=
PNS_ITEM
::
ANY
);
PNS_ITEM
*
NearestUnconnectedItem
(
PNS_JOINT
*
aStart
,
int
*
aAnchor
=
NULL
,
int
aKindMask
=
PNS_ITEM
::
ANY
);
///> finds all lines between a pair of joints. Used by the loop removal procedure.
int
FindLinesBetweenJoints
(
PNS_JOINT
&
a
,
PNS_JOINT
&
b
,
int
FindLinesBetweenJoints
(
PNS_JOINT
&
a
A
,
PNS_JOINT
&
aB
,
std
::
vector
<
PNS_LINE
*>&
aLines
);
///> finds the joints corresponding to the ends of line aLine
void
FindLineEnds
(
PNS_LINE
*
aLine
,
PNS_JOINT
&
a
,
PNS_JOINT
&
b
);
void
FindLineEnds
(
PNS_LINE
*
aLine
,
PNS_JOINT
&
a
A
,
PNS_JOINT
&
aB
);
///> Destroys all child nodes. Applicable only to the root node.
void
KillChildren
();
...
...
@@ -327,25 +321,24 @@ public:
void
ClearRanks
();
int
FindByMarker
(
int
aMarker
,
PNS_ITEMSET
&
aItems
);
int
RemoveByMarker
(
int
aMarker
);
int
FindByMarker
(
int
aMarker
,
PNS_ITEMSET
&
aItems
);
int
RemoveByMarker
(
int
aMarker
);
private
:
struct
obstacleVisitor
;
typedef
boost
::
unordered_multimap
<
PNS_JOINT
::
H
ashTag
,
PNS_JOINT
>
JointMap
;
typedef
J
ointMap
::
value_type
TagJointPair
;
struct
OBSTACLE_VISITOR
;
typedef
boost
::
unordered_multimap
<
PNS_JOINT
::
H
ASH_TAG
,
PNS_JOINT
>
JOINT_MAP
;
typedef
J
OINT_MAP
::
value_type
TagJointPair
;
/// nodes are not copyable
PNS_NODE
(
const
PNS_NODE
&
b
);
PNS_NODE
&
operator
=
(
const
PNS_NODE
&
b
);
PNS_NODE
(
const
PNS_NODE
&
aB
);
PNS_NODE
&
operator
=
(
const
PNS_NODE
&
aB
);
///> tries to find matching joint and creates a new one if not found
PNS_JOINT
&
touchJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
);
///> touches a joint and links it to an item
///> touches a joint and links it to an
m_
item
void
linkJoint
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aNet
,
PNS_ITEM
*
aWhere
);
...
...
@@ -372,26 +365,26 @@ private:
return
m_parent
==
NULL
;
}
///> checks if this branch contains an updated version of the item
///> checks if this branch contains an updated version of the
m_
item
///> from the root branch.
bool
overrides
(
PNS_ITEM
*
aItem
)
const
{
return
m_override
.
find
(
aItem
)
!=
m_override
.
end
();
}
PNS_SEGMENT
*
findRedundantSegment
(
PNS_SEGMENT
*
aSeg
);
PNS_SEGMENT
*
findRedundantSegment
(
PNS_SEGMENT
*
aSeg
);
///> scans the joint map, forming a line starting from segment (current).
void
followLine
(
PNS_SEGMENT
*
c
urrent
,
bool
s
canDirection
,
int
&
p
os
,
int
l
imit
,
VECTOR2I
*
c
orners
,
PNS_SEGMENT
**
s
egments
);
void
followLine
(
PNS_SEGMENT
*
aC
urrent
,
bool
aS
canDirection
,
int
&
aP
os
,
int
aL
imit
,
VECTOR2I
*
aC
orners
,
PNS_SEGMENT
**
aS
egments
);
///> hash table with the joints, linking the items. Joints are hashed by
///> their position, layer set and net.
J
ointMap
m_joints
;
J
OINT_MAP
m_joints
;
///> node this node was branched from
PNS_NODE
*
m_parent
;
...
...
pcbnew/router/pns_optimizer.cpp
View file @
ad1b138f
...
...
@@ -30,14 +30,11 @@
#include "pns_router.h"
/**
*
* Cost Estimator Methods
*
*/
int
PNS_COST_ESTIMATOR
::
CornerCost
(
const
SEG
&
a
,
const
SEG
&
b
)
int
PNS_COST_ESTIMATOR
::
CornerCost
(
const
SEG
&
aA
,
const
SEG
&
aB
)
{
DIRECTION_45
dir_a
(
a
),
dir_b
(
b
);
DIRECTION_45
dir_a
(
a
A
),
dir_b
(
aB
);
switch
(
dir_a
.
Angle
(
dir_b
)
)
{
...
...
@@ -109,8 +106,8 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
if
(
aOther
.
m_cornerCost
<
m_cornerCost
&&
aOther
.
m_lengthCost
<
m_lengthCost
)
return
true
;
else
if
(
aOther
.
m_cornerCost
<
m_cornerCost
*
aCornerTollerance
&&
aOther
.
m_lengthCost
<
m_lengthCost
*
aLengthTollerance
)
else
if
(
aOther
.
m_cornerCost
<
m_cornerCost
*
aCornerTollerance
&&
aOther
.
m_lengthCost
<
m_lengthCost
*
aLengthTollerance
)
return
true
;
return
false
;
...
...
@@ -118,9 +115,7 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
/**
*
* Optimizer
*
**/
PNS_OPTIMIZER
::
PNS_OPTIMIZER
(
PNS_NODE
*
aWorld
)
:
m_world
(
aWorld
),
m_collisionKindMask
(
PNS_ITEM
::
ANY
),
m_effortLevel
(
MERGE_SEGMENTS
)
...
...
@@ -135,14 +130,14 @@ PNS_OPTIMIZER::~PNS_OPTIMIZER()
}
struct
PNS_OPTIMIZER
::
C
acheVisitor
struct
PNS_OPTIMIZER
::
C
ACHE_VISITOR
{
C
acheVisitor
(
const
PNS_ITEM
*
aOurItem
,
PNS_NODE
*
aNode
,
int
aMask
)
:
C
ACHE_VISITOR
(
const
PNS_ITEM
*
aOurItem
,
PNS_NODE
*
aNode
,
int
aMask
)
:
m_ourItem
(
aOurItem
),
m_collidingItem
(
NULL
),
m_node
(
aNode
),
m_mask
(
aMask
)
{}
;
{}
bool
operator
()(
PNS_ITEM
*
aOtherItem
)
{
...
...
@@ -171,14 +166,14 @@ void PNS_OPTIMIZER::cacheAdd( PNS_ITEM* aItem, bool aIsStatic = false )
return
;
m_cache
.
Add
(
aItem
);
m_cacheTags
[
aItem
].
hits
=
1
;
m_cacheTags
[
aItem
].
isStatic
=
aIsStatic
;
m_cacheTags
[
aItem
].
m_
hits
=
1
;
m_cacheTags
[
aItem
].
m_
isStatic
=
aIsStatic
;
}
void
PNS_OPTIMIZER
::
removeCachedSegments
(
PNS_LINE
*
aLine
,
int
aStartVertex
,
int
aEndVertex
)
{
PNS_LINE
::
S
egmentRefs
*
segs
=
aLine
->
LinkedSegments
();
PNS_LINE
::
S
EGMENT_REFS
*
segs
=
aLine
->
LinkedSegments
();
if
(
!
segs
)
return
;
...
...
@@ -198,7 +193,7 @@ void PNS_OPTIMIZER::removeCachedSegments( PNS_LINE* aLine, int aStartVertex, int
void
PNS_OPTIMIZER
::
CacheRemove
(
PNS_ITEM
*
aItem
)
{
if
(
aItem
->
Kind
()
==
PNS_ITEM
::
LINE
)
removeCachedSegments
(
static_cast
<
PNS_LINE
*>
(
aItem
)
);
removeCachedSegments
(
static_cast
<
PNS_LINE
*>
(
aItem
)
);
}
...
...
@@ -219,7 +214,7 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
for
(
CachedItemTags
::
iterator
i
=
m_cacheTags
.
begin
();
i
!=
m_cacheTags
.
end
();
++
i
)
{
if
(
i
->
second
.
isStatic
)
if
(
i
->
second
.
m_
isStatic
)
{
m_cache
.
Remove
(
i
->
first
);
m_cacheTags
.
erase
(
i
->
first
);
...
...
@@ -230,7 +225,7 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
bool
PNS_OPTIMIZER
::
checkColliding
(
PNS_ITEM
*
aItem
,
bool
aUpdateCache
)
{
C
acheVisitor
v
(
aItem
,
m_world
,
m_collisionKindMask
);
C
ACHE_VISITOR
v
(
aItem
,
m_world
,
m_collisionKindMask
);
return
m_world
->
CheckColliding
(
aItem
);
...
...
@@ -239,19 +234,19 @@ bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache )
if
(
!
v
.
m_collidingItem
)
{
PNS_NODE
::
O
ptObstacle
obs
=
m_world
->
CheckColliding
(
aItem
);
PNS_NODE
::
O
PT_OBSTACLE
obs
=
m_world
->
CheckColliding
(
aItem
);
if
(
obs
)
{
if
(
aUpdateCache
)
cacheAdd
(
obs
->
item
);
cacheAdd
(
obs
->
m_
item
);
return
true
;
}
}
else
{
m_cacheTags
[
v
.
m_collidingItem
].
hits
++
;
m_cacheTags
[
v
.
m_collidingItem
].
m_
hits
++
;
return
true
;
}
...
...
@@ -430,7 +425,6 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
int
cost_orig
=
PNS_COST_ESTIMATOR
::
CornerCost
(
aCurrentPath
);
if
(
aLine
->
SegmentCount
()
<
4
)
return
false
;
...
...
@@ -442,7 +436,8 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
const
SEG
s1
=
aCurrentPath
.
CSegment
(
n
);
const
SEG
s2
=
aCurrentPath
.
CSegment
(
n
+
step
);
SHAPE_LINE_CHAIN
path
[
2
],
*
picked
=
NULL
;
SHAPE_LINE_CHAIN
path
[
2
];
SHAPE_LINE_CHAIN
*
picked
=
NULL
;
int
cost
[
2
];
for
(
int
i
=
0
;
i
<
2
;
i
++
)
...
...
@@ -485,10 +480,10 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
}
PNS_OPTIMIZER
::
B
reakoutList
PNS_OPTIMIZER
::
circleBreakouts
(
int
aWidth
,
PNS_OPTIMIZER
::
B
REAKOUT_LIST
PNS_OPTIMIZER
::
circleBreakouts
(
int
aWidth
,
const
SHAPE
*
aShape
,
bool
aPermitDiagonal
)
const
{
B
reakoutList
breakouts
;
B
REAKOUT_LIST
breakouts
;
for
(
int
angle
=
0
;
angle
<
360
;
angle
+=
45
)
{
...
...
@@ -505,12 +500,12 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::circleBreakouts( int aWidth,
}
PNS_OPTIMIZER
::
B
reakoutList
PNS_OPTIMIZER
::
rectBreakouts
(
int
aWidth
,
PNS_OPTIMIZER
::
B
REAKOUT_LIST
PNS_OPTIMIZER
::
rectBreakouts
(
int
aWidth
,
const
SHAPE
*
aShape
,
bool
aPermitDiagonal
)
const
{
const
SHAPE_RECT
*
rect
=
static_cast
<
const
SHAPE_RECT
*>
(
aShape
);
VECTOR2I
s
=
rect
->
GetSize
(),
c
=
rect
->
GetPosition
()
+
VECTOR2I
(
s
.
x
/
2
,
s
.
y
/
2
);
B
reakoutList
breakouts
;
B
REAKOUT_LIST
breakouts
;
VECTOR2I
d_offset
;
...
...
@@ -520,7 +515,6 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth,
VECTOR2I
d_vert
=
VECTOR2I
(
0
,
s
.
y
/
2
+
aWidth
);
VECTOR2I
d_horiz
=
VECTOR2I
(
s
.
x
/
2
+
aWidth
,
0
);
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
+
d_horiz
)
);
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
-
d_horiz
)
);
breakouts
.
push_back
(
SHAPE_LINE_CHAIN
(
c
,
c
+
d_vert
)
);
...
...
@@ -560,7 +554,7 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth,
}
PNS_OPTIMIZER
::
B
reakoutList
PNS_OPTIMIZER
::
computeBreakouts
(
int
aWidth
,
PNS_OPTIMIZER
::
B
REAKOUT_LIST
PNS_OPTIMIZER
::
computeBreakouts
(
int
aWidth
,
const
PNS_ITEM
*
aItem
,
bool
aPermitDiagonal
)
const
{
switch
(
aItem
->
Kind
()
)
...
...
@@ -582,7 +576,7 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::computeBreakouts( int aWidth,
case
SH_SEGMENT
:
{
const
SHAPE_SEGMENT
*
seg
=
static_cast
<
const
SHAPE_SEGMENT
*>
(
shape
);
const
SHAPE_SEGMENT
*
seg
=
static_cast
<
const
SHAPE_SEGMENT
*>
(
shape
);
const
SHAPE_RECT
rect
=
ApproximateSegmentAsRect
(
*
seg
);
return
rectBreakouts
(
aWidth
,
&
rect
,
aPermitDiagonal
);
}
...
...
@@ -599,20 +593,20 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::computeBreakouts( int aWidth,
break
;
}
return
B
reakoutList
();
return
B
REAKOUT_LIST
();
}
PNS_ITEM
*
PNS_OPTIMIZER
::
findPadOrVia
(
int
aLayer
,
int
aNet
,
const
VECTOR2I
&
aP
)
const
{
PNS_JOINT
*
jt
=
m_world
->
FindJoint
(
aP
,
aLayer
,
aNet
);
PNS_JOINT
*
jt
=
m_world
->
FindJoint
(
aP
,
aLayer
,
aNet
);
if
(
!
jt
)
return
NULL
;
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jt
->
LinkList
()
)
{
if
(
item
->
OfKind
(
PNS_ITEM
::
VIA
|
PNS_ITEM
::
SOLID
)
)
if
(
item
->
OfKind
(
PNS_ITEM
::
VIA
|
PNS_ITEM
::
SOLID
)
)
return
item
;
}
...
...
@@ -632,7 +626,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
typedef
std
::
pair
<
int
,
SHAPE_LINE_CHAIN
>
RtVariant
;
std
::
vector
<
RtVariant
>
variants
;
B
reakoutList
breakouts
=
computeBreakouts
(
aLine
->
Width
(),
aPad
,
true
);
B
REAKOUT_LIST
breakouts
=
computeBreakouts
(
aLine
->
Width
(),
aPad
,
true
);
SHAPE_LINE_CHAIN
line
=
(
aEnd
?
aLine
->
CLine
().
Reverse
()
:
aLine
->
CLine
()
);
...
...
@@ -742,6 +736,7 @@ bool PNS_OPTIMIZER::runSmartPads( PNS_LINE* aLine )
vtx
<
0
?
line
.
PointCount
()
-
1
:
line
.
PointCount
()
-
1
-
vtx
);
aLine
->
Line
().
Simplify
();
return
true
;
}
...
...
@@ -756,7 +751,7 @@ bool PNS_OPTIMIZER::Optimize( PNS_LINE* aLine, int aEffortLevel, PNS_NODE* aWorl
}
bool
PNS_OPTIMIZER
::
fanoutCleanup
(
PNS_LINE
*
aLine
)
bool
PNS_OPTIMIZER
::
fanoutCleanup
(
PNS_LINE
*
aLine
)
{
if
(
aLine
->
PointCount
()
<
3
)
return
false
;
...
...
@@ -769,40 +764,35 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE * aLine )
int
thr
=
aLine
->
Width
()
*
10
;
int
len
=
aLine
->
CLine
().
Length
();
if
(
!
startPad
)
if
(
!
startPad
)
return
false
;
bool
startMatch
=
startPad
->
OfKind
(
PNS_ITEM
::
VIA
|
PNS_ITEM
::
SOLID
);
bool
startMatch
=
startPad
->
OfKind
(
PNS_ITEM
::
VIA
|
PNS_ITEM
::
SOLID
);
bool
endMatch
=
false
;
if
(
endPad
)
{
endMatch
=
endPad
->
OfKind
(
PNS_ITEM
::
VIA
|
PNS_ITEM
::
SOLID
);
endMatch
=
endPad
->
OfKind
(
PNS_ITEM
::
VIA
|
PNS_ITEM
::
SOLID
);
}
else
{
endMatch
=
aLine
->
EndsWithVia
();
}
if
(
startMatch
&&
endMatch
&&
len
<
thr
)
if
(
startMatch
&&
endMatch
&&
len
<
thr
)
{
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
SHAPE_LINE_CHAIN
l2
=
DIRECTION_45
().
BuildInitialTrace
(
p_start
,
p_end
,
i
);
PNS_ROUTER
::
GetInstance
()
->
DisplayDebugLine
(
l2
,
4
,
10000
);
SHAPE_LINE_CHAIN
l2
=
DIRECTION_45
().
BuildInitialTrace
(
p_start
,
p_end
,
i
);
PNS_ROUTER
::
GetInstance
()
->
DisplayDebugLine
(
l2
,
4
,
10000
);
PNS_LINE
repl
;
repl
=
PNS_LINE
(
*
aLine
,
l2
);
repl
=
PNS_LINE
(
*
aLine
,
l2
);
if
(
!
m_world
->
CheckColliding
(
&
repl
))
if
(
!
m_world
->
CheckColliding
(
&
repl
)
)
{
aLine
->
SetShape
(
repl
.
CLine
()
);
aLine
->
SetShape
(
repl
.
CLine
()
);
return
true
;
}
}
}
return
false
;
}
pcbnew/router/pns_optimizer.h
View file @
ad1b138f
...
...
@@ -38,23 +38,22 @@ class PNS_ROUTER;
*
* Calculates the cost of a given line, taking corner angles and total length into account.
**/
class
PNS_COST_ESTIMATOR
{
public
:
PNS_COST_ESTIMATOR
()
:
m_lengthCost
(
0
),
m_cornerCost
(
0
)
{}
;
{}
PNS_COST_ESTIMATOR
(
const
PNS_COST_ESTIMATOR
&
b
)
:
m_lengthCost
(
b
.
m_lengthCost
),
m_cornerCost
(
b
.
m_cornerCost
)
{}
;
PNS_COST_ESTIMATOR
(
const
PNS_COST_ESTIMATOR
&
aB
)
:
m_lengthCost
(
aB
.
m_lengthCost
),
m_cornerCost
(
aB
.
m_cornerCost
)
{}
~
PNS_COST_ESTIMATOR
()
{};
static
int
CornerCost
(
const
SEG
&
a
,
const
SEG
&
b
);
static
int
CornerCost
(
const
SEG
&
a
A
,
const
SEG
&
aB
);
static
int
CornerCost
(
const
SHAPE_LINE_CHAIN
&
aLine
);
static
int
CornerCost
(
const
PNS_LINE
&
aLine
);
...
...
@@ -84,7 +83,6 @@ private:
* the procedure as long as the total cost of the line keeps decreasing
* - "Smart Pads" - that is, rerouting pad/via exits to make them look nice (SMART_PADS).
**/
class
PNS_OPTIMIZER
{
public
:
...
...
@@ -122,14 +120,14 @@ public:
private
:
static
const
int
MaxCachedItems
=
256
;
typedef
std
::
vector
<
SHAPE_LINE_CHAIN
>
B
reakoutList
;
typedef
std
::
vector
<
SHAPE_LINE_CHAIN
>
B
REAKOUT_LIST
;
struct
C
acheVisitor
;
struct
C
ACHE_VISITOR
;
struct
C
achedItem
struct
C
ACHED_ITEM
{
int
hits
;
bool
isStatic
;
int
m_
hits
;
bool
m_
isStatic
;
};
bool
mergeObtuse
(
PNS_LINE
*
aLine
);
...
...
@@ -142,15 +140,13 @@ private:
bool
checkColliding
(
PNS_ITEM
*
aItem
,
bool
aUpdateCache
=
true
);
bool
checkColliding
(
PNS_LINE
*
aLine
,
const
SHAPE_LINE_CHAIN
&
aOptPath
);
void
cacheAdd
(
PNS_ITEM
*
aItem
,
bool
aIsStatic
);
void
removeCachedSegments
(
PNS_LINE
*
aLine
,
int
aStartVertex
=
0
,
int
aEndVertex
=
-
1
);
BreakoutList
circleBreakouts
(
int
aWidth
,
const
SHAPE
*
aShape
,
bool
aPermitDiagonal
)
const
;
BreakoutList
rectBreakouts
(
int
aWidth
,
const
SHAPE
*
aShape
,
bool
aPermitDiagonal
)
const
;
BreakoutList
ovalBreakouts
(
int
aWidth
,
const
SHAPE
*
aShape
,
bool
aPermitDiagonal
)
const
;
BreakoutList
computeBreakouts
(
int
aWidth
,
const
PNS_ITEM
*
aItem
,
bool
aPermitDiagonal
)
const
;
BREAKOUT_LIST
circleBreakouts
(
int
aWidth
,
const
SHAPE
*
aShape
,
bool
aPermitDiagonal
)
const
;
BREAKOUT_LIST
rectBreakouts
(
int
aWidth
,
const
SHAPE
*
aShape
,
bool
aPermitDiagonal
)
const
;
BREAKOUT_LIST
ovalBreakouts
(
int
aWidth
,
const
SHAPE
*
aShape
,
bool
aPermitDiagonal
)
const
;
BREAKOUT_LIST
computeBreakouts
(
int
aWidth
,
const
PNS_ITEM
*
aItem
,
bool
aPermitDiagonal
)
const
;
int
smartPadsSingle
(
PNS_LINE
*
aLine
,
PNS_ITEM
*
aPad
,
bool
aEnd
,
int
aEndVertex
);
...
...
@@ -158,7 +154,7 @@ private:
SHAPE_INDEX_LIST
<
PNS_ITEM
*>
m_cache
;
typedef
boost
::
unordered_map
<
PNS_ITEM
*
,
C
achedItem
>
CachedItemTags
;
typedef
boost
::
unordered_map
<
PNS_ITEM
*
,
C
ACHED_ITEM
>
CachedItemTags
;
CachedItemTags
m_cacheTags
;
PNS_NODE
*
m_world
;
int
m_collisionKindMask
;
...
...
pcbnew/router/pns_router.cpp
View file @
ad1b138f
...
...
@@ -82,28 +82,28 @@ public:
m_defaultClearance
=
254000
;
// aBoard->m_NetClasses.Find ("Default clearance")->GetClearance();
}
int
localPadClearance
(
const
PNS_ITEM
*
i
tem
)
const
int
localPadClearance
(
const
PNS_ITEM
*
aI
tem
)
const
{
if
(
!
item
->
Parent
()
||
i
tem
->
Parent
()
->
Type
()
!=
PCB_PAD_T
)
if
(
!
aItem
->
Parent
()
||
aI
tem
->
Parent
()
->
Type
()
!=
PCB_PAD_T
)
return
0
;
const
D_PAD
*
pad
=
static_cast
<
D_PAD
*>
(
i
tem
->
Parent
()
);
const
D_PAD
*
pad
=
static_cast
<
D_PAD
*>
(
aI
tem
->
Parent
()
);
return
pad
->
GetLocalClearance
();
}
int
operator
()(
const
PNS_ITEM
*
a
,
const
PNS_ITEM
*
b
)
int
operator
()(
const
PNS_ITEM
*
a
A
,
const
PNS_ITEM
*
aB
)
{
int
net_a
=
a
->
Net
();
int
cl_a
=
(
net_a
>=
0
?
m_clearanceCache
[
net_a
]
:
m_defaultClearance
);
int
net_b
=
b
->
Net
();
int
cl_b
=
(
net_b
>=
0
?
m_clearanceCache
[
net_b
]
:
m_defaultClearance
);
int
net_a
=
a
A
->
Net
();
int
cl_a
=
(
net_a
>=
0
?
m_clearanceCache
[
net_a
]
:
m_defaultClearance
);
int
net_b
=
aB
->
Net
();
int
cl_b
=
(
net_b
>=
0
?
m_clearanceCache
[
net_b
]
:
m_defaultClearance
);
int
pad_a
=
localPadClearance
(
a
);
int
pad_b
=
localPadClearance
(
b
);
int
pad_a
=
localPadClearance
(
a
A
);
int
pad_b
=
localPadClearance
(
aB
);
cl_a
=
std
::
max
(
cl_a
,
pad_a
);
cl_b
=
std
::
max
(
cl_b
,
pad_b
);
cl_a
=
std
::
max
(
cl_a
,
pad_a
);
cl_b
=
std
::
max
(
cl_b
,
pad_b
);
return
std
::
max
(
cl_a
,
cl_b
);
}
...
...
@@ -113,9 +113,10 @@ private:
int
m_defaultClearance
;
};
PNS_ITEM
*
PNS_ROUTER
::
syncPad
(
D_PAD
*
aPad
)
{
PNS_LAYERSET
layers
(
0
,
15
);
PNS_LAYERSET
layers
(
0
,
15
);
switch
(
aPad
->
GetAttribute
()
)
{
...
...
@@ -131,7 +132,7 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
for
(
i
=
FIRST_COPPER_LAYER
;
i
<=
LAST_COPPER_LAYER
;
i
++
)
{
if
(
lmsk
&
(
1
<<
i
)
)
if
(
lmsk
&
(
1
<<
i
)
)
{
layers
=
PNS_LAYERSET
(
i
);
break
;
...
...
@@ -162,17 +163,16 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
double
orient
=
aPad
->
GetOrientation
()
/
10.0
;
bool
nonOrtho
=
false
;
if
(
orient
==
90.0
||
orient
==
270.0
)
sz
=
VECTOR2I
(
sz
.
y
,
sz
.
x
);
else
if
(
orient
!=
0.0
&&
orient
!=
180.0
)
{
// rotated pads are replaced by for the moment by circles due to my laziness ;)
solid
->
SetShape
(
new
SHAPE_CIRCLE
(
c
,
std
::
min
(
sz
.
x
,
sz
.
y
)
/
2
)
);
solid
->
SetShape
(
new
SHAPE_CIRCLE
(
c
,
std
::
min
(
sz
.
x
,
sz
.
y
)
/
2
)
);
nonOrtho
=
true
;
}
if
(
!
nonOrtho
)
if
(
!
nonOrtho
)
{
switch
(
aPad
->
GetShape
()
)
{
...
...
@@ -183,15 +183,17 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
case
PAD_OVAL
:
if
(
sz
.
x
==
sz
.
y
)
solid
->
SetShape
(
new
SHAPE_CIRCLE
(
c
,
sz
.
x
/
2
)
);
else
{
else
{
VECTOR2I
delta
;
if
(
sz
.
x
>
sz
.
y
)
delta
=
VECTOR2I
(
(
sz
.
x
-
sz
.
y
)
/
2
,
0
);
if
(
sz
.
x
>
sz
.
y
)
delta
=
VECTOR2I
(
(
sz
.
x
-
sz
.
y
)
/
2
,
0
);
else
delta
=
VECTOR2I
(
0
,
(
sz
.
y
-
sz
.
x
)
/
2
);
delta
=
VECTOR2I
(
0
,
(
sz
.
y
-
sz
.
x
)
/
2
);
SHAPE_SEGMENT
*
shape
=
new
SHAPE_SEGMENT
(
c
-
delta
,
c
+
delta
,
std
::
min
(
sz
.
x
,
sz
.
y
)
);
SHAPE_SEGMENT
*
shape
=
new
SHAPE_SEGMENT
(
c
-
delta
,
c
+
delta
,
std
::
min
(
sz
.
x
,
sz
.
y
)
);
solid
->
SetShape
(
shape
);
}
break
;
...
...
@@ -203,6 +205,7 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
default
:
TRACEn
(
0
,
"unsupported pad shape"
);
delete
solid
;
return
NULL
;
}
}
...
...
@@ -250,7 +253,8 @@ int PNS_ROUTER::NextCopperLayer( bool aUp )
LAYER_MSK
mask
=
m_board
->
GetEnabledLayers
()
&
m_board
->
GetVisibleLayers
();
LAYER_NUM
l
=
m_currentLayer
;
do
{
do
{
l
+=
(
aUp
?
1
:
-
1
);
if
(
l
>
LAST_COPPER_LAYER
)
...
...
@@ -261,7 +265,8 @@ int PNS_ROUTER::NextCopperLayer( bool aUp )
if
(
mask
&
GetLayerMask
(
l
)
)
return
l
;
}
while
(
l
!=
m_currentLayer
);
}
while
(
l
!=
m_currentLayer
);
return
l
;
}
...
...
@@ -269,7 +274,6 @@ int PNS_ROUTER::NextCopperLayer( bool aUp )
void
PNS_ROUTER
::
SyncWorld
()
{
if
(
!
m_board
)
{
TRACEn
(
0
,
"No board attached, aborting sync."
);
...
...
@@ -379,13 +383,6 @@ void PNS_ROUTER::ClearWorld()
}
/*void PNS_ROUTER::SetCurrentWidth( int w )
{
// fixme: change width while routing
m_currentWidth = w;
}*/
bool
PNS_ROUTER
::
RoutingInProgress
()
const
{
return
m_state
!=
IDLE
;
...
...
@@ -405,31 +402,31 @@ const PNS_ITEMSET PNS_ROUTER::QueryHoverItems( const VECTOR2I& aP )
}
const
VECTOR2I
PNS_ROUTER
::
SnapToItem
(
PNS_ITEM
*
i
tem
,
VECTOR2I
aP
,
bool
&
aSplitsSegment
)
const
VECTOR2I
PNS_ROUTER
::
SnapToItem
(
PNS_ITEM
*
aI
tem
,
VECTOR2I
aP
,
bool
&
aSplitsSegment
)
{
VECTOR2I
anchor
;
if
(
!
i
tem
)
if
(
!
aI
tem
)
{
aSplitsSegment
=
false
;
return
aP
;
}
switch
(
i
tem
->
Kind
()
)
switch
(
aI
tem
->
Kind
()
)
{
case
PNS_ITEM
:
:
SOLID
:
anchor
=
static_cast
<
PNS_SOLID
*>
(
item
)
->
Pos
();
anchor
=
static_cast
<
PNS_SOLID
*>
(
aItem
)
->
Pos
();
aSplitsSegment
=
false
;
break
;
case
PNS_ITEM
:
:
VIA
:
anchor
=
static_cast
<
PNS_VIA
*>
(
item
)
->
Pos
();
anchor
=
static_cast
<
PNS_VIA
*>
(
aItem
)
->
Pos
();
aSplitsSegment
=
false
;
break
;
case
PNS_ITEM
:
:
SEGMENT
:
{
PNS_SEGMENT
*
seg
=
static_cast
<
PNS_SEGMENT
*>
(
i
tem
);
PNS_SEGMENT
*
seg
=
static_cast
<
PNS_SEGMENT
*>
(
aI
tem
);
const
SEG
&
s
=
seg
->
Seg
();
int
w
=
seg
->
Width
();
...
...
@@ -455,16 +452,19 @@ const VECTOR2I PNS_ROUTER::SnapToItem( PNS_ITEM* item, VECTOR2I aP, bool& aSplit
return
anchor
;
}
bool
PNS_ROUTER
::
StartDragging
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aStartItem
)
{
if
(
!
aStartItem
||
aStartItem
->
OfKind
(
PNS_ITEM
::
SOLID
)
)
if
(
!
aStartItem
||
aStartItem
->
OfKind
(
PNS_ITEM
::
SOLID
)
)
return
false
;
m_dragger
=
new
PNS_DRAGGER
(
this
);
m_dragger
->
SetWorld
(
m_world
);
if
(
m_dragger
->
Start
(
aP
,
aStartItem
)
)
m_state
=
DRAG_SEGMENT
;
else
{
else
{
delete
m_dragger
;
m_state
=
IDLE
;
return
false
;
...
...
@@ -476,8 +476,6 @@ bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem )
bool
PNS_ROUTER
::
StartRouting
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aStartItem
)
{
m_state
=
ROUTE_TRACK
;
m_placer
=
new
PNS_LINE_PLACER
(
this
);
...
...
@@ -518,11 +516,11 @@ void PNS_ROUTER::DisplayItem( const PNS_ITEM* aItem, int aColor, int aClearance
{
ROUTER_PREVIEW_ITEM
*
pitem
=
new
ROUTER_PREVIEW_ITEM
(
aItem
,
m_previewItems
);
if
(
aColor
>=
0
)
pitem
->
SetColor
(
KIGFX
::
COLOR4D
(
aColor
)
);
if
(
aColor
>=
0
)
pitem
->
SetColor
(
KIGFX
::
COLOR4D
(
aColor
)
);
if
(
aClearance
>=
0
)
pitem
->
SetClearance
(
aClearance
);
if
(
aClearance
>=
0
)
pitem
->
SetClearance
(
aClearance
);
m_previewItems
->
Add
(
pitem
);
...
...
@@ -530,12 +528,14 @@ void PNS_ROUTER::DisplayItem( const PNS_ITEM* aItem, int aColor, int aClearance
m_previewItems
->
ViewUpdate
(
KIGFX
::
VIEW_ITEM
::
GEOMETRY
|
KIGFX
::
VIEW_ITEM
::
APPEARANCE
);
}
void
PNS_ROUTER
::
DisplayItems
(
const
PNS_ITEMSET
&
aItems
)
{
BOOST_FOREACH
(
const
PNS_ITEM
*
item
,
aItems
.
CItems
()
)
DisplayItem
(
item
);
BOOST_FOREACH
(
const
PNS_ITEM
*
item
,
aItems
.
CItems
()
)
DisplayItem
(
item
);
}
void
PNS_ROUTER
::
DisplayDebugLine
(
const
SHAPE_LINE_CHAIN
&
aLine
,
int
aType
,
int
aWidth
)
{
ROUTER_PREVIEW_ITEM
*
pitem
=
new
ROUTER_PREVIEW_ITEM
(
NULL
,
m_previewItems
);
...
...
@@ -547,18 +547,17 @@ void PNS_ROUTER::DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType, int
}
void
PNS_ROUTER
::
DisplayDebugPoint
(
const
VECTOR2I
pos
,
int
aType
)
void
PNS_ROUTER
::
DisplayDebugPoint
(
const
VECTOR2I
aPos
,
int
aType
)
{
ROUTER_PREVIEW_ITEM
*
pitem
=
new
ROUTER_PREVIEW_ITEM
(
NULL
,
m_previewItems
);
pitem
->
Point
(
p
os
,
aType
);
pitem
->
Point
(
aP
os
,
aType
);
m_previewItems
->
Add
(
pitem
);
pitem
->
ViewSetVisible
(
true
);
m_previewItems
->
ViewUpdate
(
KIGFX
::
VIEW_ITEM
::
GEOMETRY
|
KIGFX
::
VIEW_ITEM
::
APPEARANCE
);
}
void
PNS_ROUTER
::
Move
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
endItem
)
{
m_currentEnd
=
aP
;
...
...
@@ -573,57 +572,62 @@ void PNS_ROUTER::Move( const VECTOR2I& aP, PNS_ITEM* endItem )
case
DRAG_SEGMENT
:
moveDragging
(
aP
,
endItem
);
break
;
default
:
break
;
}
}
void
PNS_ROUTER
::
moveDragging
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
endItem
)
void
PNS_ROUTER
::
moveDragging
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aEndItem
)
{
eraseView
();
m_dragger
->
Drag
(
aP
);
PNS_ITEMSET
dragged
=
m_dragger
->
Traces
();
updateView
(
m_dragger
->
CurrentNode
(
),
dragged
);
updateView
(
m_dragger
->
CurrentNode
(
),
dragged
);
}
void
PNS_ROUTER
::
markViolations
(
PNS_NODE
*
aNode
,
PNS_ITEMSET
&
aCurrent
,
PNS_NODE
::
ItemVector
&
aRemoved
)
{
BOOST_FOREACH
(
PNS_ITEM
*
item
,
aCurrent
.
Items
())
void
PNS_ROUTER
::
markViolations
(
PNS_NODE
*
aNode
,
PNS_ITEMSET
&
aCurrent
,
PNS_NODE
::
ITEM_VECTOR
&
aRemoved
)
{
BOOST_FOREACH
(
PNS_ITEM
*
item
,
aCurrent
.
Items
()
)
{
PNS_NODE
::
O
bstacles
obstacles
;
PNS_NODE
::
O
BSTACLES
obstacles
;
aNode
->
QueryColliding
(
item
,
obstacles
,
PNS_ITEM
::
ANY
);
if
(
item
->
OfKind
(
PNS_ITEM
::
LINE
)
)
if
(
item
->
OfKind
(
PNS_ITEM
::
LINE
)
)
{
PNS_LINE
*
l
=
static_cast
<
PNS_LINE
*>
(
item
);
if
(
l
->
EndsWithVia
())
PNS_LINE
*
l
=
static_cast
<
PNS_LINE
*>
(
item
);
if
(
l
->
EndsWithVia
()
)
{
PNS_VIA
v
(
l
->
Via
()
);
aNode
->
QueryColliding
(
&
v
,
obstacles
,
PNS_ITEM
::
ANY
);
aNode
->
QueryColliding
(
&
v
,
obstacles
,
PNS_ITEM
::
ANY
);
}
}
BOOST_FOREACH
(
PNS_OBSTACLE
&
obs
,
obstacles
)
BOOST_FOREACH
(
PNS_OBSTACLE
&
obs
,
obstacles
)
{
int
clearance
=
aNode
->
GetClearance
(
item
,
obs
.
item
);
std
::
auto_ptr
<
PNS_ITEM
>
tmp
(
obs
.
item
->
Clone
()
);
tmp
->
Mark
(
MK_VIOLATION
);
int
clearance
=
aNode
->
GetClearance
(
item
,
obs
.
m_
item
);
std
::
auto_ptr
<
PNS_ITEM
>
tmp
(
obs
.
m_
item
->
Clone
()
);
tmp
->
Mark
(
MK_VIOLATION
);
DisplayItem
(
tmp
.
get
(),
-
1
,
clearance
);
aRemoved
.
push_back
(
obs
.
item
);
aRemoved
.
push_back
(
obs
.
m_item
);
}
}
}
void
PNS_ROUTER
::
updateView
(
PNS_NODE
*
aNode
,
PNS_ITEMSET
&
aCurrent
)
void
PNS_ROUTER
::
updateView
(
PNS_NODE
*
aNode
,
PNS_ITEMSET
&
aCurrent
)
{
PNS_NODE
::
I
temVector
removed
,
added
;
PNS_NODE
::
O
bstacles
obstacles
;
PNS_NODE
::
I
TEM_VECTOR
removed
,
added
;
PNS_NODE
::
O
BSTACLES
obstacles
;
if
(
!
aNode
)
if
(
!
aNode
)
return
;
if
(
Settings
().
Mode
()
==
RM_MarkObstacles
)
...
...
@@ -661,15 +665,14 @@ void PNS_ROUTER::ApplySettings()
m_placer
->
Move
(
m_currentEnd
,
m_currentEndItem
);
movePlacing
(
m_currentEnd
,
m_currentEndItem
);
}
// TODO handle mode/optimization/other options change
}
void
PNS_ROUTER
::
movePlacing
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
endItem
)
void
PNS_ROUTER
::
movePlacing
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aEndItem
)
{
eraseView
();
m_placer
->
Move
(
aP
,
e
ndItem
);
m_placer
->
Move
(
aP
,
aE
ndItem
);
PNS_LINE
current
=
m_placer
->
Trace
();
DisplayItem
(
&
current
);
...
...
@@ -681,9 +684,10 @@ void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* endItem )
updateView
(
m_placer
->
CurrentNode
(
true
),
tmp
);
}
void
PNS_ROUTER
::
CommitRouting
(
PNS_NODE
*
aNode
)
{
PNS_NODE
::
I
temVector
removed
,
added
;
PNS_NODE
::
I
TEM_VECTOR
removed
,
added
;
aNode
->
GetUpdatedItems
(
removed
,
added
);
...
...
@@ -770,34 +774,33 @@ PNS_VIA* PNS_ROUTER::checkLoneVia( PNS_JOINT* aJoint ) const
return
NULL
;
}
bool
PNS_ROUTER
::
FixRoute
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aEndItem
)
{
bool
rv
=
false
;
switch
(
m_state
)
switch
(
m_state
)
{
case
ROUTE_TRACK
:
rv
=
m_placer
->
FixRoute
(
aP
,
aEndItem
);
rv
=
m_placer
->
FixRoute
(
aP
,
aEndItem
);
m_placingVia
=
false
;
break
;
case
DRAG_SEGMENT
:
rv
=
m_dragger
->
FixRoute
();
rv
=
m_dragger
->
FixRoute
();
break
;
default
:
break
;
}
if
(
rv
)
if
(
rv
)
StopRouting
();
return
rv
;
}
void
PNS_ROUTER
::
StopRouting
()
{
// Update the ratsnest with new changes
...
...
@@ -806,10 +809,10 @@ void PNS_ROUTER::StopRouting()
if
(
!
RoutingInProgress
()
)
return
;
if
(
m_placer
)
if
(
m_placer
)
delete
m_placer
;
if
(
m_dragger
)
if
(
m_dragger
)
delete
m_dragger
;
m_placer
=
NULL
;
...
...
@@ -825,7 +828,7 @@ void PNS_ROUTER::StopRouting()
void
PNS_ROUTER
::
FlipPosture
()
{
if
(
m_state
==
ROUTE_TRACK
)
if
(
m_state
==
ROUTE_TRACK
)
{
m_placer
->
FlipPosture
();
m_placer
->
Move
(
m_currentEnd
,
m_currentEndItem
);
...
...
@@ -833,22 +836,23 @@ void PNS_ROUTER::FlipPosture()
}
void
PNS_ROUTER
::
SwitchLayer
(
int
l
ayer
)
void
PNS_ROUTER
::
SwitchLayer
(
int
aL
ayer
)
{
switch
(
m_state
)
{
case
IDLE
:
m_currentLayer
=
l
ayer
;
m_currentLayer
=
aL
ayer
;
break
;
case
ROUTE_TRACK
:
if
(
m_startsOnVia
)
{
m_currentLayer
=
l
ayer
;
m_currentLayer
=
aL
ayer
;
//m_placer->StartPlacement( m_currentStart, m_currentNet, m_currentWidth,
// m_currentLayer );
}
break
;
default
:
break
;
}
...
...
@@ -864,32 +868,38 @@ void PNS_ROUTER::ToggleViaPlacement()
}
}
int
PNS_ROUTER
::
GetCurrentNet
()
const
{
switch
(
m_state
)
switch
(
m_state
)
{
case
ROUTE_TRACK
:
return
m_placer
->
CurrentNet
();
default
:
return
m_currentNet
;
}
}
int
PNS_ROUTER
::
GetCurrentLayer
()
const
{
switch
(
m_state
)
switch
(
m_state
)
{
case
ROUTE_TRACK
:
return
m_placer
->
CurrentLayer
();
default
:
return
m_currentLayer
;
}
}
void
PNS_ROUTER
::
DumpLog
()
{
PNS_LOGGER
*
logger
=
NULL
;
switch
(
m_state
)
PNS_LOGGER
*
logger
=
NULL
;
switch
(
m_state
)
{
case
DRAG_SEGMENT
:
logger
=
m_dragger
->
Logger
();
...
...
@@ -899,6 +909,6 @@ void PNS_ROUTER::DumpLog()
break
;
}
if
(
logger
)
if
(
logger
)
logger
->
Save
(
"/tmp/shove.log"
);
}
pcbnew/router/pns_router.h
View file @
ad1b138f
...
...
@@ -51,9 +51,10 @@ class PNS_CLEARANCE_FUNC;
class
PNS_SHOVE
;
class
PNS_DRAGGER
;
namespace
KIGFX
{
class
VIEW
;
class
VIEW_GROUP
;
namespace
KIGFX
{
class
VIEW
;
class
VIEW_GROUP
;
};
...
...
@@ -62,7 +63,6 @@ class VIEW_GROUP;
*
* Main router class.
*/
class
PNS_ROUTER
{
private
:
...
...
@@ -94,7 +94,7 @@ public:
const
VECTOR2I
CurrentEnd
()
const
;
int
GetClearance
(
const
PNS_ITEM
*
a
,
const
PNS_ITEM
*
b
)
const
;
int
GetClearance
(
const
PNS_ITEM
*
a
A
,
const
PNS_ITEM
*
aB
)
const
;
PNS_NODE
*
GetWorld
()
const
{
...
...
@@ -114,8 +114,8 @@ public:
void
ToggleViaPlacement
();
int
GetCurrentLayer
()
const
;
// { return m_currentLayer; }
int
GetCurrentNet
()
const
;
// { return m_currentNet; }
int
GetCurrentLayer
()
const
;
int
GetCurrentNet
()
const
;
void
DumpLog
();
...
...
@@ -134,14 +134,19 @@ public:
// typedef boost::optional<hoverItem> optHoverItem;
const
PNS_ITEMSET
QueryHoverItems
(
const
VECTOR2I
&
aP
);
const
VECTOR2I
SnapToItem
(
PNS_ITEM
*
i
tem
,
VECTOR2I
aP
,
bool
&
aSplitsSegment
);
const
VECTOR2I
SnapToItem
(
PNS_ITEM
*
aI
tem
,
VECTOR2I
aP
,
bool
&
aSplitsSegment
);
bool
StartDragging
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aItem
);
void
SetIterLimit
(
int
aX
)
{
m_iterLimit
=
aX
;
}
int
GetIterLimit
()
const
{
return
m_iterLimit
;
};
void
SetShowIntermediateSteps
(
bool
aX
,
int
aSnapshotIter
=
-
1
)
{
m_showInterSteps
=
aX
;
m_snapshotIter
=
aSnapshotIter
;
}
void
SetShowIntermediateSteps
(
bool
aX
,
int
aSnapshotIter
=
-
1
)
{
m_showInterSteps
=
aX
;
m_snapshotIter
=
aSnapshotIter
;
}
bool
GetShowIntermediateSteps
()
const
{
return
m_showInterSteps
;
}
int
GetShapshotIter
()
const
{
return
m_snapshotIter
;
}
...
...
@@ -168,7 +173,7 @@ public:
/**
* Applies stored settings.
*
\
see Settings()
*
@
see Settings()
*/
void
ApplySettings
();
...
...
@@ -183,30 +188,29 @@ public:
ApplySettings
();
}
void
EnableSnapping
(
bool
aEnable
)
void
EnableSnapping
(
bool
aEnable
)
{
m_snappingEnabled
=
aEnable
;
}
bool
SnappingEnabled
()
const
bool
SnappingEnabled
()
const
{
return
m_snappingEnabled
;
}
private
:
void
movePlacing
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aItem
);
void
moveDragging
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aItem
);
void
movePlacing
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aItem
);
void
moveDragging
(
const
VECTOR2I
&
aP
,
PNS_ITEM
*
aItem
);
void
eraseView
();
void
updateView
(
PNS_NODE
*
aNode
,
PNS_ITEMSET
&
aCurrent
);
//PNS_LINE *aCurrent = NULL
);
void
updateView
(
PNS_NODE
*
aNode
,
PNS_ITEMSET
&
aCurrent
);
void
clearViewFlags
();
// optHoverItem queryHoverItemEx(const VECTOR2I& aP);
PNS_ITEM
*
pickSingleItem
(
PNS_ITEMSET
&
aItems
)
const
;
// std::vector<PNS_ITEM*> aItems) const;
void
splitAdjacentSegments
(
PNS_NODE
*
aNode
,
PNS_ITEM
*
aSeg
,
const
VECTOR2I
&
aP
);
// optHoverItem& aItem);
PNS_ITEM
*
pickSingleItem
(
PNS_ITEMSET
&
aItems
)
const
;
void
splitAdjacentSegments
(
PNS_NODE
*
aNode
,
PNS_ITEM
*
aSeg
,
const
VECTOR2I
&
aP
);
PNS_VIA
*
checkLoneVia
(
PNS_JOINT
*
aJoint
)
const
;
PNS_ITEM
*
syncPad
(
D_PAD
*
aPad
);
...
...
@@ -219,7 +223,7 @@ private:
void
highlightCurrent
(
bool
enabled
);
void
markViolations
(
PNS_NODE
*
aNode
,
PNS_ITEMSET
&
aCurrent
,
PNS_NODE
::
I
temVector
&
aRemoved
);
void
markViolations
(
PNS_NODE
*
aNode
,
PNS_ITEMSET
&
aCurrent
,
PNS_NODE
::
I
TEM_VECTOR
&
aRemoved
);
int
m_currentLayer
;
int
m_currentNet
;
...
...
@@ -241,8 +245,7 @@ private:
KIGFX
::
VIEW
*
m_view
;
KIGFX
::
VIEW_GROUP
*
m_previewItems
;
PNS_ITEM
*
m_currentEndItem
;
PNS_ITEM
*
m_currentEndItem
;
VECTOR2I
m_currentEnd
;
VECTOR2I
m_currentStart
;
...
...
@@ -252,7 +255,7 @@ private:
bool
m_snappingEnabled
;
bool
m_violation
;
// optHoverItem m_startItem, m_endItem;
// optHoverItem m_startItem, m_endItem;
PNS_ROUTING_SETTINGS
m_settings
;
PNS_CLEARANCE_FUNC
*
m_clearanceFunc
;
...
...
pcbnew/router/pns_routing_settings.cpp
View file @
ad1b138f
...
...
@@ -23,7 +23,7 @@
PNS_ROUTING_SETTINGS
::
PNS_ROUTING_SETTINGS
()
{
m_routingMode
=
RM_Walkaround
;
m_optimizerEffort
=
OE_F
ull
;
m_optimizerEffort
=
OE_F
ULL
;
m_removeLoops
=
true
;
m_smartPads
=
true
;
m_shoveVias
=
true
;
...
...
@@ -38,11 +38,13 @@ PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS()
m_canViolateDRC
=
false
;
}
TIME_LIMIT
PNS_ROUTING_SETTINGS
::
ShoveTimeLimit
()
const
{
return
TIME_LIMIT
(
m_shoveTimeLimit
);
}
int
PNS_ROUTING_SETTINGS
::
ShoveIterationLimit
()
const
{
return
m_shoveIterationLimit
;
...
...
pcbnew/router/pns_routing_settings.h
View file @
ad1b138f
...
...
@@ -36,9 +36,9 @@ enum PNS_MODE
///> Optimization effort
enum
PNS_OPTIMIZATION_EFFORT
{
OE_L
ow
=
0
,
OE_M
edium
=
1
,
OE_F
ull
=
2
OE_L
OW
=
0
,
OE_M
EDIUM
=
1
,
OE_F
ULL
=
2
};
/**
...
...
@@ -91,7 +91,7 @@ public:
///> Returns true if follow mouse mode is active (permanently on for the moment).
bool
FollowMouse
()
const
{
return
m_followMouse
&&
!
(
Mode
()
==
RM_MarkObstacles
);
return
m_followMouse
&&
!
(
Mode
()
==
RM_MarkObstacles
);
}
///> Returns true if smoothing segments durign dragging is enabled.
...
...
@@ -120,10 +120,10 @@ public:
const
DIRECTION_45
InitialDirection
()
const
{
if
(
m_startDiagonal
)
return
DIRECTION_45
(
DIRECTION_45
::
NE
);
if
(
m_startDiagonal
)
return
DIRECTION_45
(
DIRECTION_45
::
NE
);
else
return
DIRECTION_45
(
DIRECTION_45
::
N
);
return
DIRECTION_45
(
DIRECTION_45
::
N
);
}
int
ShoveIterationLimit
()
const
;
...
...
@@ -133,7 +133,6 @@ public:
TIME_LIMIT
WalkaroundTimeLimit
()
const
;
private
:
bool
m_shoveVias
;
bool
m_startDiagonal
;
bool
m_removeLoops
;
...
...
pcbnew/router/pns_segment.h
View file @
ad1b138f
...
...
@@ -37,17 +37,17 @@ class PNS_SEGMENT : public PNS_ITEM
public
:
PNS_SEGMENT
()
:
PNS_ITEM
(
SEGMENT
)
{}
;
{}
PNS_SEGMENT
(
const
SEG
&
aSeg
,
int
aNet
)
:
PNS_ITEM
(
SEGMENT
),
m_seg
(
aSeg
,
0
)
PNS_ITEM
(
SEGMENT
),
m_seg
(
aSeg
,
0
)
{
m_net
=
aNet
;
}
;
}
PNS_SEGMENT
(
const
PNS_LINE
&
aParentLine
,
const
SEG
&
aSeg
)
:
PNS_ITEM
(
SEGMENT
),
m_seg
(
aSeg
,
aParentLine
.
Width
()
)
m_seg
(
aSeg
,
aParentLine
.
Width
()
)
{
m_net
=
aParentLine
.
Net
();
m_layers
=
aParentLine
.
Layers
();
...
...
@@ -55,7 +55,6 @@ public:
m_rank
=
aParentLine
.
Rank
();
};
PNS_SEGMENT
*
Clone
(
)
const
;
const
SHAPE
*
Shape
()
const
...
...
@@ -101,14 +100,14 @@ public:
void
SwapEnds
()
{
SEG
tmp
=
m_seg
.
GetSeg
();
m_seg
.
SetSeg
(
SEG
(
tmp
.
B
,
tmp
.
A
));
m_seg
.
SetSeg
(
SEG
(
tmp
.
B
,
tmp
.
A
)
);
}
const
SHAPE_LINE_CHAIN
Hull
(
int
aClearance
,
int
aWalkaroundThickness
)
const
;
virtual
VECTOR2I
Anchor
(
int
n
)
const
{
if
(
n
==
0
)
if
(
n
==
0
)
return
m_seg
.
GetSeg
().
A
;
else
return
m_seg
.
GetSeg
().
B
;
...
...
pcbnew/router/pns_shove.cpp
View file @
ad1b138f
...
...
@@ -41,63 +41,70 @@
#include <profile.h>
static
void
sanityCheck
(
PNS_LINE
*
l_old
,
PNS_LINE
*
l_new
)
static
void
sanityCheck
(
PNS_LINE
*
aOld
,
PNS_LINE
*
aNew
)
{
assert
(
l_old
->
CPoint
(
0
)
==
l_new
->
CPoint
(
0
)
);
assert
(
l_old
->
CPoint
(
-
1
)
==
l_new
->
CPoint
(
-
1
)
);
assert
(
aOld
->
CPoint
(
0
)
==
aNew
->
CPoint
(
0
)
);
assert
(
aOld
->
CPoint
(
-
1
)
==
aNew
->
CPoint
(
-
1
)
);
}
PNS_SHOVE
::
PNS_SHOVE
(
PNS_NODE
*
aWorld
,
PNS_ROUTER
*
aRouter
)
:
PNS_SHOVE
::
PNS_SHOVE
(
PNS_NODE
*
aWorld
,
PNS_ROUTER
*
aRouter
)
:
PNS_ALGO_BASE
(
aRouter
)
{
m_root
=
aWorld
;
}
;
}
PNS_SHOVE
::~
PNS_SHOVE
()
{
// free all the stuff we've created during routing/dragging operation.
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_gcItems
)
// free all the stuff we've created during routing/dragging operation.
BOOST_FOREACH
(
PNS_ITEM
*
item
,
m_gcItems
)
delete
item
;
}
// garbage-collected line assembling
PNS_LINE
*
PNS_SHOVE
::
assembleLine
(
const
PNS_SEGMENT
*
aSeg
,
int
*
aIndex
)
PNS_LINE
*
PNS_SHOVE
::
assembleLine
(
const
PNS_SEGMENT
*
aSeg
,
int
*
aIndex
)
{
PNS_LINE
*
l
=
m_currentNode
->
AssembleLine
(
const_cast
<
PNS_SEGMENT
*
>
(
aSeg
),
aIndex
);
PNS_LINE
*
l
=
m_currentNode
->
AssembleLine
(
const_cast
<
PNS_SEGMENT
*>
(
aSeg
),
aIndex
);
m_gcItems
.
push_back
(
l
);
return
l
;
}
// garbage-collected line cloning
PNS_LINE
*
PNS_SHOVE
::
cloneLine
(
const
PNS_LINE
*
aLine
)
{
PNS_LINE
*
l
=
aLine
->
Clone
();
m_gcItems
.
push_back
(
l
);
m_gcItems
.
push_back
(
l
);
return
l
;
}
// A dumb function that checks if the shoved line is shoved the right way, e.g.
// visually "outwards" of the line/via applying pressure on it. Unfortunately there's no
// mathematical concept of orientation of an open curve, so we use some primitive heuristics:
// if the shoved line wraps around the start of the "pusher", it's likely shoved in wrong direction.
bool
PNS_SHOVE
::
checkBumpDirection
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aShoved
)
const
bool
PNS_SHOVE
::
checkBumpDirection
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aShoved
)
const
{
const
SEG
ss
=
aCurrent
->
CSegment
(
0
);
const
SEG
ss
=
aCurrent
->
CSegment
(
0
);
int
dist
=
m_currentNode
->
GetClearance
(
aCurrent
,
aShoved
)
+
PNS_HULL_MARGIN
;
int
dist
=
m_currentNode
->
GetClearance
(
aCurrent
,
aShoved
)
+
PNS_HULL_MARGIN
;
dist
+=
aCurrent
->
Width
()
/
2
;
dist
+=
aShoved
->
Width
()
/
2
;
const
VECTOR2I
ps
=
ss
.
A
-
(
ss
.
B
-
ss
.
A
).
Resize
(
dist
);
const
VECTOR2I
ps
=
ss
.
A
-
(
ss
.
B
-
ss
.
A
).
Resize
(
dist
);
return
!
aShoved
->
CLine
().
PointOnEdge
(
ps
);
return
!
aShoved
->
CLine
().
PointOnEdge
(
ps
);
}
PNS_SHOVE
::
ShoveStatus
PNS_SHOVE
::
walkaroundLoneVia
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
)
PNS_SHOVE
::
SHOVE_STATUS
PNS_SHOVE
::
walkaroundLoneVia
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
)
{
int
clearance
=
m_currentNode
->
GetClearance
(
aCurrent
,
aObstacle
);
const
SHAPE_LINE_CHAIN
hull
=
aCurrent
->
Via
().
Hull
(
clearance
,
aObstacle
->
Width
()
);
...
...
@@ -108,11 +115,13 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::walkaroundLoneVia ( PNS_LINE *aCurrent, PNS_LI
const
SHAPE_LINE_CHAIN
&
shortest
=
path_ccw
.
Length
()
<
path_cw
.
Length
()
?
path_ccw
:
path_cw
;
if
(
shortest
.
PointCount
()
<
2
)
if
(
shortest
.
PointCount
()
<
2
)
return
SH_INCOMPLETE
;
if
(
aObstacle
->
CPoint
(
-
1
)
!=
shortest
.
CPoint
(
-
1
))
if
(
aObstacle
->
CPoint
(
-
1
)
!=
shortest
.
CPoint
(
-
1
)
)
return
SH_INCOMPLETE
;
if
(
aObstacle
->
CPoint
(
0
)
!=
shortest
.
CPoint
(
0
))
if
(
aObstacle
->
CPoint
(
0
)
!=
shortest
.
CPoint
(
0
)
)
return
SH_INCOMPLETE
;
aShoved
->
SetShape
(
shortest
);
...
...
@@ -123,33 +132,35 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::walkaroundLoneVia ( PNS_LINE *aCurrent, PNS_LI
return
SH_OK
;
}
PNS_SHOVE
::
ShoveStatus
PNS_SHOVE
::
processHullSet
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
,
const
HullSet
&
hulls
)
PNS_SHOVE
::
SHOVE_STATUS
PNS_SHOVE
::
processHullSet
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
,
const
HULL_SET
&
aHulls
)
{
const
SHAPE_LINE_CHAIN
&
obs
=
aObstacle
->
CLine
();
bool
failingDirCheck
=
false
;
int
attempt
;
for
(
attempt
=
0
;
attempt
<
4
;
attempt
++
)
for
(
attempt
=
0
;
attempt
<
4
;
attempt
++
)
{
bool
invertTraversal
=
(
attempt
>=
2
);
bool
invertTraversal
=
(
attempt
>=
2
);
bool
clockwise
=
attempt
%
2
;
int
vFirst
=
-
1
,
vLast
=
-
1
;
SHAPE_LINE_CHAIN
path
;
PNS_LINE
l
(
*
aObstacle
);
PNS_LINE
l
(
*
aObstacle
);
for
(
int
i
=
0
;
i
<
(
int
)
h
ulls
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
aH
ulls
.
size
();
i
++
)
{
const
SHAPE_LINE_CHAIN
&
hull
=
hulls
[
invertTraversal
?
h
ulls
.
size
()
-
1
-
i
:
i
];
const
SHAPE_LINE_CHAIN
&
hull
=
aHulls
[
invertTraversal
?
aH
ulls
.
size
()
-
1
-
i
:
i
];
l
.
Walkaround
(
hull
,
path
,
clockwise
);
path
.
Simplify
();
l
.
SetShape
(
path
);
}
for
(
int
i
=
0
;
i
<
std
::
min
(
path
.
PointCount
(),
obs
.
PointCount
()
);
i
++
)
for
(
int
i
=
0
;
i
<
std
::
min
(
path
.
PointCount
(),
obs
.
PointCount
()
);
i
++
)
{
if
(
path
.
CPoint
(
i
)
!=
obs
.
CPoint
(
i
)
)
if
(
path
.
CPoint
(
i
)
!=
obs
.
CPoint
(
i
)
)
{
vFirst
=
i
;
break
;
...
...
@@ -157,36 +168,37 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE
}
int
k
=
obs
.
PointCount
()
-
1
;
for
(
int
i
=
path
.
PointCount
()
-
1
;
i
>=
0
&&
k
>=
0
;
i
--
,
k
--
)
for
(
int
i
=
path
.
PointCount
()
-
1
;
i
>=
0
&&
k
>=
0
;
i
--
,
k
--
)
{
if
(
path
.
CPoint
(
i
)
!=
obs
.
CPoint
(
k
)
)
if
(
path
.
CPoint
(
i
)
!=
obs
.
CPoint
(
k
)
)
{
vLast
=
i
;
break
;
}
}
if
(
(
vFirst
<
0
||
vLast
<
0
)
&&
!
path
.
CompareGeometry
(
aObstacle
->
CLine
()
)
)
if
(
(
vFirst
<
0
||
vLast
<
0
)
&&
!
path
.
CompareGeometry
(
aObstacle
->
CLine
()
)
)
{
TRACE
(
100
,
"attempt %d fail vfirst-last"
,
attempt
);
continue
;
}
if
(
path
.
CPoint
(
-
1
)
!=
obs
.
CPoint
(
-
1
)
||
path
.
CPoint
(
0
)
!=
obs
.
CPoint
(
0
)
)
if
(
path
.
CPoint
(
-
1
)
!=
obs
.
CPoint
(
-
1
)
||
path
.
CPoint
(
0
)
!=
obs
.
CPoint
(
0
)
)
{
TRACE
(
100
,
"attempt %d fail vend-start
\n
"
,
attempt
);
TRACE
(
100
,
"attempt %d fail vend-start
\n
"
,
attempt
);
continue
;
}
if
(
!
checkBumpDirection
(
aCurrent
,
&
l
)
)
if
(
!
checkBumpDirection
(
aCurrent
,
&
l
)
)
{
TRACE
(
100
,
"attempt %d fail direction-check"
,
attempt
);
failingDirCheck
=
true
;
aShoved
->
SetShape
(
l
.
CLine
());
aShoved
->
SetShape
(
l
.
CLine
()
);
continue
;
}
if
(
path
.
SelfIntersecting
()
)
if
(
path
.
SelfIntersecting
()
)
{
TRACE
(
100
,
"attempt %d fail self-intersect"
,
attempt
);
continue
;
...
...
@@ -194,13 +206,13 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE
bool
colliding
=
m_currentNode
->
CheckColliding
(
&
l
,
aCurrent
);
if
(
(
aCurrent
->
Marker
()
&
MK_HEAD
)
&&
!
colliding
)
if
(
(
aCurrent
->
Marker
()
&
MK_HEAD
)
&&
!
colliding
)
{
PNS_JOINT
*
jtStart
=
m_currentNode
->
FindJoint
(
aCurrent
->
CPoint
(
0
),
aCurrent
);
PNS_JOINT
*
jtStart
=
m_currentNode
->
FindJoint
(
aCurrent
->
CPoint
(
0
),
aCurrent
);
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jtStart
->
LinkList
()
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jtStart
->
LinkList
()
)
{
if
(
m_currentNode
->
CheckColliding
(
item
,
&
l
)
)
if
(
m_currentNode
->
CheckColliding
(
item
,
&
l
)
)
colliding
=
true
;
}
}
...
...
@@ -219,7 +231,9 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE
return
failingDirCheck
?
SH_OK
:
SH_INCOMPLETE
;
}
PNS_SHOVE
::
ShoveStatus
PNS_SHOVE
::
processSingleLine
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
)
PNS_SHOVE
::
SHOVE_STATUS
PNS_SHOVE
::
processSingleLine
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
)
{
aShoved
->
ClearSegmentLinks
();
...
...
@@ -227,73 +241,75 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processSingleLine ( PNS_LINE *aCurrent, PNS_LI
if
(
aObstacle
->
LinkedSegments
()
)
{
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
aObstacle
->
LinkedSegments
()
)
if
(
s
->
Marker
()
&
MK_HEAD
)
BOOST_FOREACH
(
PNS_SEGMENT
*
s
,
*
aObstacle
->
LinkedSegments
()
)
if
(
s
->
Marker
()
&
MK_HEAD
)
{
obstacleIsHead
=
true
;
break
;
}
}
S
hoveStatus
rv
;
S
HOVE_STATUS
rv
;
bool
viaOnEnd
=
aCurrent
->
EndsWithVia
();
if
(
viaOnEnd
&&
(
!
aCurrent
->
LayersOverlap
(
aObstacle
)
||
aCurrent
->
SegmentCount
()
==
0
)
)
{
rv
=
walkaroundLoneVia
(
aCurrent
,
aObstacle
,
aShoved
);
}
else
{
}
else
{
int
w
=
aObstacle
->
Width
();
int
n_segs
=
aCurrent
->
SegmentCount
();
int
clearance
=
m_currentNode
->
GetClearance
(
aCurrent
,
aObstacle
);
H
ullSet
hulls
;
H
ULL_SET
hulls
;
hulls
.
reserve
(
n_segs
+
1
);
for
(
int
i
=
0
;
i
<
n_segs
;
i
++
)
{
PNS_SEGMENT
seg
(
*
aCurrent
,
aCurrent
->
CSegment
(
i
)
);
hulls
.
push_back
(
seg
.
Hull
(
clearance
,
w
)
);
PNS_SEGMENT
seg
(
*
aCurrent
,
aCurrent
->
CSegment
(
i
)
);
hulls
.
push_back
(
seg
.
Hull
(
clearance
,
w
)
);
}
if
(
viaOnEnd
)
hulls
.
push_back
(
aCurrent
->
Via
().
Hull
(
clearance
,
w
)
);
rv
=
processHullSet
(
aCurrent
,
aObstacle
,
aShoved
,
hulls
);
rv
=
processHullSet
(
aCurrent
,
aObstacle
,
aShoved
,
hulls
);
}
if
(
obstacleIsHead
)
if
(
obstacleIsHead
)
aShoved
->
Mark
(
aShoved
->
Marker
()
|
MK_HEAD
);
return
rv
;
}
PNS_SHOVE
::
S
hoveStatus
PNS_SHOVE
::
onCollidingSegment
(
PNS_LINE
*
aCurrent
,
PNS_SEGMENT
*
aObstacleSeg
)
PNS_SHOVE
::
S
HOVE_STATUS
PNS_SHOVE
::
onCollidingSegment
(
PNS_LINE
*
aCurrent
,
PNS_SEGMENT
*
aObstacleSeg
)
{
int
segIndex
;
PNS_LINE
*
obstacleLine
=
assembleLine
(
aObstacleSeg
,
&
segIndex
);
PNS_LINE
*
shovedLine
=
cloneLine
(
obstacleLine
);
PNS_LINE
*
obstacleLine
=
assembleLine
(
aObstacleSeg
,
&
segIndex
);
PNS_LINE
*
shovedLine
=
cloneLine
(
obstacleLine
);
S
hoveStatus
rv
=
processSingleLine
(
aCurrent
,
obstacleLine
,
shovedLine
);
S
HOVE_STATUS
rv
=
processSingleLine
(
aCurrent
,
obstacleLine
,
shovedLine
);
assert
(
obstacleLine
->
LayersOverlap
(
shovedLine
)
);
assert
(
obstacleLine
->
LayersOverlap
(
shovedLine
)
);
if
(
rv
==
SH_OK
)
if
(
rv
==
SH_OK
)
{
if
(
shovedLine
->
Marker
()
&
MK_HEAD
)
m_newHead
=
*
shovedLine
;
sanityCheck
(
obstacleLine
,
shovedLine
);
m_currentNode
->
Replace
(
obstacleLine
,
shovedLine
);
sanityCheck
(
obstacleLine
,
shovedLine
);
sanityCheck
(
obstacleLine
,
shovedLine
);
m_currentNode
->
Replace
(
obstacleLine
,
shovedLine
);
sanityCheck
(
obstacleLine
,
shovedLine
);
int
rank
=
aCurrent
->
Rank
();
shovedLine
->
SetRank
(
rank
-
1
);
shovedLine
->
SetRank
(
rank
-
1
);
pushLine
(
shovedLine
);
pushLine
(
shovedLine
);
}
#ifdef DEBUG
...
...
@@ -307,64 +323,64 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSegment( PNS_LINE *aCurrent, PNS_SE
return
rv
;
}
PNS_SHOVE
::
ShoveStatus
PNS_SHOVE
::
onCollidingLine
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
)
PNS_SHOVE
::
SHOVE_STATUS
PNS_SHOVE
::
onCollidingLine
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
)
{
PNS_LINE
*
shovedLine
=
cloneLine
(
aObstacle
);
PNS_LINE
*
shovedLine
=
cloneLine
(
aObstacle
);
S
hoveStatus
rv
=
processSingleLine
(
aCurrent
,
aObstacle
,
shovedLine
);
S
HOVE_STATUS
rv
=
processSingleLine
(
aCurrent
,
aObstacle
,
shovedLine
);
if
(
rv
==
SH_OK
)
if
(
rv
==
SH_OK
)
{
if
(
shovedLine
->
Marker
()
&
MK_HEAD
)
m_newHead
=
*
shovedLine
;
sanityCheck
(
aObstacle
,
shovedLine
);
sanityCheck
(
aObstacle
,
shovedLine
);
m_currentNode
->
Replace
(
aObstacle
,
shovedLine
);
sanityCheck
(
aObstacle
,
shovedLine
);
sanityCheck
(
aObstacle
,
shovedLine
);
int
rank
=
aObstacle
->
Rank
();
shovedLine
->
SetRank
(
rank
);
pushLine
(
shovedLine
);
pushLine
(
shovedLine
);
#ifdef DEBUG
m_logger
.
NewGroup
(
"on-colliding-line"
,
m_iter
);
m_logger
.
Log
(
aObstacle
,
0
,
"obstacle-line"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
m_logger
.
Log
(
shovedLine
,
3
,
"shoved-line"
);
m_logger
.
NewGroup
(
"on-colliding-line"
,
m_iter
);
m_logger
.
Log
(
aObstacle
,
0
,
"obstacle-line"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
m_logger
.
Log
(
shovedLine
,
3
,
"shoved-line"
);
#endif
}
return
rv
;
}
PNS_SHOVE
::
ShoveStatus
PNS_SHOVE
::
onCollidingSolid
(
PNS_LINE
*
aCurrent
,
PNS_SOLID
*
aObstacleSolid
)
PNS_SHOVE
::
SHOVE_STATUS
PNS_SHOVE
::
onCollidingSolid
(
PNS_LINE
*
aCurrent
,
PNS_SOLID
*
aObstacleSolid
)
{
PNS_WALKAROUND
walkaround
(
m_currentNode
,
Router
()
);
PNS_LINE
*
walkaroundLine
=
cloneLine
(
aCurrent
);
PNS_LINE
*
walkaroundLine
=
cloneLine
(
aCurrent
);
if
(
aCurrent
->
EndsWithVia
()
)
if
(
aCurrent
->
EndsWithVia
()
)
{
PNS_VIA
vh
=
aCurrent
->
Via
();
PNS_VIA
*
via
=
NULL
;
PNS_JOINT
*
jtStart
=
m_currentNode
->
FindJoint
(
vh
.
Pos
(),
aCurrent
);
PNS_VIA
*
via
=
NULL
;
PNS_JOINT
*
jtStart
=
m_currentNode
->
FindJoint
(
vh
.
Pos
(),
aCurrent
);
if
(
!
jtStart
)
if
(
!
jtStart
)
return
SH_INCOMPLETE
;
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jtStart
->
LinkList
()
)
if
(
item
->
OfKind
(
PNS_ITEM
::
VIA
))
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jtStart
->
LinkList
()
)
{
if
(
item
->
OfKind
(
PNS_ITEM
::
VIA
)
)
{
via
=
(
PNS_VIA
*
)
item
;
via
=
(
PNS_VIA
*
)
item
;
break
;
}
}
if
(
via
&&
m_currentNode
->
CheckColliding
(
via
,
aObstacleSolid
)
)
return
onCollidingVia
(
aObstacleSolid
,
via
);
if
(
via
&&
m_currentNode
->
CheckColliding
(
via
,
aObstacleSolid
)
)
return
onCollidingVia
(
aObstacleSolid
,
via
);
}
walkaround
.
SetSolidsOnly
(
true
);
...
...
@@ -373,45 +389,45 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSolid( PNS_LINE *aCurrent, PNS_SOLI
int
currentRank
=
aCurrent
->
Rank
();
int
nextRank
;
if
(
!
Settings
().
JumpOverObstacles
()
)
if
(
!
Settings
().
JumpOverObstacles
()
)
{
nextRank
=
currentRank
+
10000
;
walkaround
.
SetSingleDirection
(
false
);
}
else
{
}
else
{
nextRank
=
currentRank
-
1
;
walkaround
.
SetSingleDirection
(
true
);
}
if
(
walkaround
.
Route
(
*
aCurrent
,
*
walkaroundLine
,
false
)
!=
PNS_WALKAROUND
::
DONE
)
if
(
walkaround
.
Route
(
*
aCurrent
,
*
walkaroundLine
,
false
)
!=
PNS_WALKAROUND
::
DONE
)
return
SH_INCOMPLETE
;
walkaroundLine
->
ClearSegmentLinks
();
walkaroundLine
->
Unmark
();
walkaroundLine
->
Line
().
Simplify
();
if
(
walkaroundLine
->
HasLoops
()
)
if
(
walkaroundLine
->
HasLoops
()
)
return
SH_INCOMPLETE
;
if
(
aCurrent
->
Marker
()
&
MK_HEAD
)
if
(
aCurrent
->
Marker
()
&
MK_HEAD
)
{
walkaroundLine
->
Mark
(
MK_HEAD
);
walkaroundLine
->
Mark
(
MK_HEAD
);
m_newHead
=
*
walkaroundLine
;
}
m_currentNode
->
Replace
(
aCurrent
,
walkaroundLine
);
walkaroundLine
->
SetRank
(
nextRank
);
#ifdef DEBUG
m_logger
.
NewGroup
(
"on-colliding-solid"
,
m_iter
);
m_logger
.
Log
(
aObstacleSolid
,
0
,
"obstacle-solid"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
m_logger
.
Log
(
walkaroundLine
,
3
,
"walk-line"
);
m_logger
.
NewGroup
(
"on-colliding-solid"
,
m_iter
);
m_logger
.
Log
(
aObstacleSolid
,
0
,
"obstacle-solid"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
m_logger
.
Log
(
walkaroundLine
,
3
,
"walk-line"
);
#endif
popLine
();
pushLine
(
walkaroundLine
);
pushLine
(
walkaroundLine
);
return
SH_OK
;
}
...
...
@@ -423,13 +439,13 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet )
while
(
!
m_nodeStack
.
empty
()
)
{
S
pringbackTag
spTag
=
m_nodeStack
.
back
();
S
PRINGBACK_TAG
spTag
=
m_nodeStack
.
back
();
if
(
!
spTag
.
node
->
CheckColliding
(
aHeadSet
)
)
if
(
!
spTag
.
m_
node
->
CheckColliding
(
aHeadSet
)
)
{
rv
=
true
;
delete
spTag
.
node
;
delete
spTag
.
m_
node
;
m_nodeStack
.
pop_back
();
}
else
...
...
@@ -440,98 +456,99 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet )
}
bool
PNS_SHOVE
::
pushSpringback
(
PNS_NODE
*
aNode
,
const
PNS_ITEMSET
&
aHeadItems
,
const
PNS_COST_ESTIMATOR
&
aCost
)
bool
PNS_SHOVE
::
pushSpringback
(
PNS_NODE
*
aNode
,
const
PNS_ITEMSET
&
aHeadItems
,
const
PNS_COST_ESTIMATOR
&
aCost
)
{
S
pringbackTag
st
;
S
PRINGBACK_TAG
st
;
st
.
node
=
aNode
;
st
.
cost
=
aCost
;
st
.
headItems
=
aHeadItems
;
st
.
m_
node
=
aNode
;
st
.
m_
cost
=
aCost
;
st
.
m_
headItems
=
aHeadItems
;
m_nodeStack
.
push_back
(
st
);
return
true
;
}
PNS_SHOVE
::
S
hoveStatus
PNS_SHOVE
::
pushVia
(
PNS_VIA
*
aVia
,
const
VECTOR2I
&
aForce
,
int
aCurrentRank
)
PNS_SHOVE
::
S
HOVE_STATUS
PNS_SHOVE
::
pushVia
(
PNS_VIA
*
aVia
,
const
VECTOR2I
&
aForce
,
int
aCurrentRank
)
{
LinePairVec
draggedLines
;
LINE_PAIR_VEC
draggedLines
;
VECTOR2I
p0
(
aVia
->
Pos
()
);
PNS_JOINT
*
jt
=
m_currentNode
->
FindJoint
(
p0
,
1
,
aVia
->
Net
()
);
PNS_VIA
*
pushedVia
=
aVia
->
Clone
();
PNS_JOINT
*
jt
=
m_currentNode
->
FindJoint
(
p0
,
1
,
aVia
->
Net
()
);
PNS_VIA
*
pushedVia
=
aVia
->
Clone
();
pushedVia
->
SetPos
(
p0
+
aForce
);
pushedVia
->
Mark
(
aVia
->
Marker
()
)
;
pushedVia
->
Mark
(
aVia
->
Marker
()
);
if
(
aVia
->
Marker
()
&
MK_HEAD
)
if
(
aVia
->
Marker
()
&
MK_HEAD
)
{
m_draggedVia
=
pushedVia
;
}
if
(
!
jt
)
if
(
!
jt
)
{
TRACEn
(
1
,
"weird, can't find the center-of-via joint
\n
"
);
TRACEn
(
1
,
"weird, can't find the center-of-via joint
\n
"
);
return
SH_INCOMPLETE
;
}
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jt
->
LinkList
()
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jt
->
LinkList
()
)
{
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
)
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
)
{
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
item
;
L
inePair
lp
;
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
item
;
L
INE_PAIR
lp
;
int
segIndex
;
lp
.
first
=
assembleLine
(
seg
,
&
segIndex
);
lp
.
first
=
assembleLine
(
seg
,
&
segIndex
);
assert
(
segIndex
==
0
||
(
segIndex
==
(
lp
.
first
->
SegmentCount
()
-
1
)
)
);
assert
(
segIndex
==
0
||
(
segIndex
==
(
lp
.
first
->
SegmentCount
()
-
1
)
)
);
if
(
segIndex
==
0
)
if
(
segIndex
==
0
)
lp
.
first
->
Reverse
();
lp
.
second
=
cloneLine
(
lp
.
first
);
lp
.
second
->
ClearSegmentLinks
();
lp
.
second
->
DragCorner
(
p0
+
aForce
,
lp
.
second
->
CLine
().
Find
(
p0
));
lp
.
second
->
DragCorner
(
p0
+
aForce
,
lp
.
second
->
CLine
().
Find
(
p0
)
);
lp
.
second
->
AppendVia
(
*
pushedVia
);
draggedLines
.
push_back
(
lp
);
draggedLines
.
push_back
(
lp
);
}
}
m_currentNode
->
Remove
(
aVia
);
m_currentNode
->
Add
(
pushedVia
);
if
(
aVia
->
BelongsTo
(
m_currentNode
)
)
if
(
aVia
->
BelongsTo
(
m_currentNode
)
)
delete
aVia
;
pushedVia
->
SetRank
(
aCurrentRank
-
1
);
pushedVia
->
SetRank
(
aCurrentRank
-
1
);
#ifdef DEBUG
m_logger
.
Log
(
aVia
,
0
,
"obstacle-via"
);
m_logger
.
Log
(
pushedVia
,
1
,
"pushed-via"
);
#endif
BOOST_FOREACH
(
L
inePair
lp
,
draggedLines
)
BOOST_FOREACH
(
L
INE_PAIR
lp
,
draggedLines
)
{
if
(
lp
.
first
->
Marker
()
&
MK_HEAD
)
if
(
lp
.
first
->
Marker
()
&
MK_HEAD
)
{
lp
.
second
->
Mark
(
MK_HEAD
);
lp
.
second
->
Mark
(
MK_HEAD
);
m_newHead
=
*
lp
.
second
;
}
unwindStack
(
lp
.
first
);
if
(
lp
.
second
->
SegmentCount
()
)
if
(
lp
.
second
->
SegmentCount
()
)
{
m_currentNode
->
Replace
(
lp
.
first
,
lp
.
second
);
lp
.
second
->
SetRank
(
aCurrentRank
-
1
);
pushLine
(
lp
.
second
);
}
else
m_currentNode
->
Remove
(
lp
.
first
);
m_currentNode
->
Replace
(
lp
.
first
,
lp
.
second
);
lp
.
second
->
SetRank
(
aCurrentRank
-
1
);
pushLine
(
lp
.
second
);
}
else
m_currentNode
->
Remove
(
lp
.
first
);
#ifdef DEBUG
m_logger
.
Log
(
lp
.
first
,
2
,
"fan-pre"
);
m_logger
.
Log
(
lp
.
second
,
3
,
"fan-post"
);
m_logger
.
Log
(
lp
.
first
,
2
,
"fan-pre"
);
m_logger
.
Log
(
lp
.
second
,
3
,
"fan-post"
);
#endif
}
...
...
@@ -539,108 +556,112 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::pushVia ( PNS_VIA *aVia, const VECTOR2I& aForc
}
PNS_SHOVE
::
S
hoveStatus
PNS_SHOVE
::
onCollidingVia
(
PNS_ITEM
*
aCurrent
,
PNS_VIA
*
aObstacleVia
)
PNS_SHOVE
::
S
HOVE_STATUS
PNS_SHOVE
::
onCollidingVia
(
PNS_ITEM
*
aCurrent
,
PNS_VIA
*
aObstacleVia
)
{
int
clearance
=
m_currentNode
->
GetClearance
(
aCurrent
,
aObstacleVia
)
;
L
inePairVec
draggedLines
;
VECTOR2I
p0
(
aObstacleVia
->
Pos
()
);
L
INE_PAIR_VEC
draggedLines
;
VECTOR2I
p0
(
aObstacleVia
->
Pos
()
);
bool
colLine
=
false
,
colVia
=
false
;
PNS_LINE
*
currentLine
=
NULL
;
VECTOR2I
mtvLine
,
mtvVia
,
mtv
,
mtvSolid
;
int
rank
=
-
1
;
if
(
aCurrent
->
OfKind
(
PNS_ITEM
::
LINE
)
)
if
(
aCurrent
->
OfKind
(
PNS_ITEM
::
LINE
)
)
{
#ifdef DEBUG
m_logger
.
NewGroup
(
"push-via-by-line"
,
m_iter
);
m_logger
.
Log
(
aCurrent
,
4
,
"current"
);
m_logger
.
NewGroup
(
"push-via-by-line"
,
m_iter
);
m_logger
.
Log
(
aCurrent
,
4
,
"current"
);
#endif
currentLine
=
(
PNS_LINE
*
)
aCurrent
;
colLine
=
CollideShapes
(
aObstacleVia
->
Shape
(),
currentLine
->
Shape
(),
clearance
+
currentLine
->
Width
()
/
2
+
PNS_HULL_MARGIN
,
true
,
mtvLine
);
colLine
=
CollideShapes
(
aObstacleVia
->
Shape
(),
currentLine
->
Shape
(),
clearance
+
currentLine
->
Width
()
/
2
+
PNS_HULL_MARGIN
,
true
,
mtvLine
);
if
(
currentLine
->
EndsWithVia
())
colVia
=
CollideShapes
(
currentLine
->
Via
().
Shape
(),
aObstacleVia
->
Shape
(),
clearance
+
PNS_HULL_MARGIN
,
true
,
mtvVia
);
if
(
currentLine
->
EndsWithVia
()
)
colVia
=
CollideShapes
(
currentLine
->
Via
().
Shape
(),
aObstacleVia
->
Shape
(),
clearance
+
PNS_HULL_MARGIN
,
true
,
mtvVia
);
if
(
!
colLine
&&
!
colVia
)
if
(
!
colLine
&&
!
colVia
)
return
SH_OK
;
if
(
colLine
&&
colVia
)
if
(
colLine
&&
colVia
)
mtv
=
mtvVia
.
EuclideanNorm
()
>
mtvLine
.
EuclideanNorm
()
?
mtvVia
:
mtvLine
;
else
if
(
colLine
)
else
if
(
colLine
)
mtv
=
mtvLine
;
else
mtv
=
mtvVia
;
rank
=
currentLine
->
Rank
();
}
else
if
(
aCurrent
->
OfKind
(
PNS_ITEM
::
SOLID
))
{
CollideShapes
(
aObstacleVia
->
Shape
(),
aCurrent
->
Shape
(),
clearance
+
PNS_HULL_MARGIN
,
true
,
mtvSolid
);
CollideShapes
(
aObstacleVia
->
Shape
(),
aCurrent
->
Shape
(),
clearance
+
PNS_HULL_MARGIN
,
true
,
mtvSolid
);
mtv
=
mtvSolid
;
rank
=
aCurrent
->
Rank
()
+
10000
;
}
return
pushVia
(
aObstacleVia
,
mtv
,
rank
);
return
pushVia
(
aObstacleVia
,
mtv
,
rank
);
}
PNS_SHOVE
::
ShoveStatus
PNS_SHOVE
::
onReverseCollidingVia
(
PNS_LINE
*
aCurrent
,
PNS_VIA
*
aObstacleVia
)
PNS_SHOVE
::
SHOVE_STATUS
PNS_SHOVE
::
onReverseCollidingVia
(
PNS_LINE
*
aCurrent
,
PNS_VIA
*
aObstacleVia
)
{
std
::
vector
<
PNS_LINE
*>
steps
;
std
::
vector
<
PNS_LINE
*>
steps
;
int
n
=
0
;
PNS_LINE
*
cur
=
cloneLine
(
aCurrent
);
PNS_LINE
*
cur
=
cloneLine
(
aCurrent
);
cur
->
ClearSegmentLinks
();
PNS_JOINT
*
jt
=
m_currentNode
->
FindJoint
(
aObstacleVia
->
Pos
(),
aObstacleVia
);
PNS_LINE
*
shoved
=
cloneLine
(
aCurrent
);
PNS_JOINT
*
jt
=
m_currentNode
->
FindJoint
(
aObstacleVia
->
Pos
(),
aObstacleVia
);
PNS_LINE
*
shoved
=
cloneLine
(
aCurrent
);
shoved
->
ClearSegmentLinks
();
cur
->
RemoveVia
();
unwindStack
(
aCurrent
);
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jt
->
LinkList
()
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jt
->
LinkList
()
)
{
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
&&
item
->
LayersOverlap
(
aCurrent
)
)
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
&&
item
->
LayersOverlap
(
aCurrent
)
)
{
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
item
;
PNS_LINE
*
head
=
assembleLine
(
seg
);
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
item
;
PNS_LINE
*
head
=
assembleLine
(
seg
);
head
->
AppendVia
(
*
aObstacleVia
);
S
hoveStatus
st
=
processSingleLine
(
head
,
cur
,
shoved
);
S
HOVE_STATUS
st
=
processSingleLine
(
head
,
cur
,
shoved
);
if
(
st
!=
SH_OK
)
{
#ifdef DEBUG
m_logger
.
NewGroup
(
"on-reverse-via-fail-shove"
,
m_iter
);
m_logger
.
Log
(
aObstacleVia
,
0
,
"the-via"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
m_logger
.
Log
(
shoved
,
3
,
"shoved-line"
);
m_logger
.
NewGroup
(
"on-reverse-via-fail-shove"
,
m_iter
);
m_logger
.
Log
(
aObstacleVia
,
0
,
"the-via"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
m_logger
.
Log
(
shoved
,
3
,
"shoved-line"
);
#endif
return
st
;
}
cur
->
SetShape
(
shoved
->
CLine
()
);
cur
->
SetShape
(
shoved
->
CLine
()
);
n
++
;
}
}
if
(
!
n
)
if
(
!
n
)
{
#ifdef DEBUG
m_logger
.
NewGroup
(
"on-reverse-via-fail-lonevia"
,
m_iter
);
m_logger
.
Log
(
aObstacleVia
,
0
,
"the-via"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
m_logger
.
NewGroup
(
"on-reverse-via-fail-lonevia"
,
m_iter
);
m_logger
.
Log
(
aObstacleVia
,
0
,
"the-via"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
#endif
PNS_LINE
head
(
*
aCurrent
);
PNS_LINE
head
(
*
aCurrent
);
head
.
Line
().
Clear
();
head
.
AppendVia
(
*
aObstacleVia
);
head
.
ClearSegmentLinks
();
S
hoveStatus
st
=
processSingleLine
(
&
head
,
aCurrent
,
shoved
);
S
HOVE_STATUS
st
=
processSingleLine
(
&
head
,
aCurrent
,
shoved
);
if
(
st
!=
SH_OK
)
return
st
;
...
...
@@ -648,96 +669,103 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onReverseCollidingVia (PNS_LINE *aCurrent, PNS
cur
->
SetShape
(
shoved
->
CLine
()
);
}
if
(
aCurrent
->
EndsWithVia
()
)
shoved
->
AppendVia
(
aCurrent
->
Via
(
)
);
if
(
aCurrent
->
EndsWithVia
()
)
shoved
->
AppendVia
(
aCurrent
->
Via
(
)
);
#ifdef DEBUG
m_logger
.
NewGroup
(
"on-reverse-via"
,
m_iter
);
m_logger
.
Log
(
aObstacleVia
,
0
,
"the-via"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
m_logger
.
Log
(
shoved
,
3
,
"shoved-line"
);
m_logger
.
NewGroup
(
"on-reverse-via"
,
m_iter
);
m_logger
.
Log
(
aObstacleVia
,
0
,
"the-via"
);
m_logger
.
Log
(
aCurrent
,
1
,
"current-line"
);
m_logger
.
Log
(
shoved
,
3
,
"shoved-line"
);
#endif
int
currentRank
=
aCurrent
->
Rank
();
m_currentNode
->
Replace
(
aCurrent
,
shoved
);
pushLine
(
shoved
);
pushLine
(
shoved
);
shoved
->
SetRank
(
currentRank
);
return
SH_OK
;
}
void
PNS_SHOVE
::
unwindStack
(
PNS_SEGMENT
*
s
eg
)
void
PNS_SHOVE
::
unwindStack
(
PNS_SEGMENT
*
aS
eg
)
{
for
(
std
::
vector
<
PNS_LINE
*>::
iterator
i
=
m_lineStack
.
begin
();
i
!=
m_lineStack
.
end
();
)
for
(
std
::
vector
<
PNS_LINE
*>::
iterator
i
=
m_lineStack
.
begin
();
i
!=
m_lineStack
.
end
();
)
{
if
(
(
*
i
)
->
ContainsSegment
(
s
eg
)
)
if
(
(
*
i
)
->
ContainsSegment
(
aS
eg
)
)
i
=
m_lineStack
.
erase
(
i
);
else
i
++
;
}
for
(
std
::
vector
<
PNS_LINE
*>::
iterator
i
=
m_optimizerQueue
.
begin
();
i
!=
m_optimizerQueue
.
end
();
)
for
(
std
::
vector
<
PNS_LINE
*>::
iterator
i
=
m_optimizerQueue
.
begin
();
i
!=
m_optimizerQueue
.
end
();
)
{
if
(
(
*
i
)
->
ContainsSegment
(
s
eg
)
)
if
(
(
*
i
)
->
ContainsSegment
(
aS
eg
)
)
i
=
m_optimizerQueue
.
erase
(
i
);
else
i
++
;
}
}
void
PNS_SHOVE
::
unwindStack
(
PNS_ITEM
*
item
)
void
PNS_SHOVE
::
unwindStack
(
PNS_ITEM
*
aItem
)
{
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
))
unwindStack
(
static_cast
<
PNS_SEGMENT
*>
(
item
));
else
if
(
item
->
OfKind
(
PNS_ITEM
::
LINE
))
{
PNS_LINE
*
l
=
static_cast
<
PNS_LINE
*>
(
item
);
if
(
aItem
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
)
unwindStack
(
static_cast
<
PNS_SEGMENT
*>
(
aItem
)
);
else
if
(
aItem
->
OfKind
(
PNS_ITEM
::
LINE
)
)
{
PNS_LINE
*
l
=
static_cast
<
PNS_LINE
*>
(
aItem
);
if
(
!
l
->
LinkedSegments
()
)
if
(
!
l
->
LinkedSegments
()
)
return
;
BOOST_FOREACH
(
PNS_SEGMENT
*
seg
,
*
l
->
LinkedSegments
()
)
unwindStack
(
seg
);
BOOST_FOREACH
(
PNS_SEGMENT
*
seg
,
*
l
->
LinkedSegments
()
)
unwindStack
(
seg
);
}
}
void
PNS_SHOVE
::
pushLine
(
PNS_LINE
*
l
)
void
PNS_SHOVE
::
pushLine
(
PNS_LINE
*
aL
)
{
if
(
l
->
LinkCount
()
>=
0
&&
(
l
->
LinkCount
()
!=
l
->
SegmentCount
())
)
assert
(
false
);
if
(
aL
->
LinkCount
()
>=
0
&&
(
aL
->
LinkCount
()
!=
aL
->
SegmentCount
()
)
)
assert
(
false
);
m_lineStack
.
push_back
(
l
);
m_optimizerQueue
.
push_back
(
l
);
m_lineStack
.
push_back
(
aL
);
m_optimizerQueue
.
push_back
(
aL
);
}
void
PNS_SHOVE
::
popLine
(
)
{
PNS_LINE
*
l
=
m_lineStack
.
back
();
PNS_LINE
*
l
=
m_lineStack
.
back
();
for
(
std
::
vector
<
PNS_LINE
*>::
iterator
i
=
m_optimizerQueue
.
begin
();
i
!=
m_optimizerQueue
.
end
();
)
for
(
std
::
vector
<
PNS_LINE
*>::
iterator
i
=
m_optimizerQueue
.
begin
();
i
!=
m_optimizerQueue
.
end
();
)
{
if
(
(
*
i
)
==
l
)
if
(
(
*
i
)
==
l
)
{
i
=
m_optimizerQueue
.
erase
(
i
);
}
else
}
else
i
++
;
}
m_lineStack
.
pop_back
();
}
PNS_SHOVE
::
ShoveStatus
PNS_SHOVE
::
shoveIteration
(
int
aIter
)
PNS_SHOVE
::
SHOVE_STATUS
PNS_SHOVE
::
shoveIteration
(
int
aIter
)
{
PNS_LINE
*
currentLine
=
m_lineStack
.
back
();
PNS_NODE
::
O
ptObstacle
nearest
;
S
hoveStatus
st
;
PNS_NODE
::
O
PT_OBSTACLE
nearest
;
S
HOVE_STATUS
st
;
PNS_ITEM
::
PnsKind
search_order
[]
=
{
PNS_ITEM
::
SOLID
,
PNS_ITEM
::
VIA
,
PNS_ITEM
::
SEGMENT
};
for
(
int
i
=
0
;
i
<
3
;
i
++
)
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
nearest
=
m_currentNode
->
NearestObstacle
(
currentLine
,
search_order
[
i
]
);
if
(
nearest
)
if
(
nearest
)
break
;
}
...
...
@@ -747,23 +775,25 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
return
SH_OK
;
}
PNS_ITEM
*
ni
=
nearest
->
item
;
PNS_ITEM
*
ni
=
nearest
->
m_
item
;
unwindStack
(
ni
);
unwindStack
(
ni
);
if
(
!
ni
->
OfKind
(
PNS_ITEM
::
SOLID
)
&&
ni
->
Rank
()
>=
0
&&
ni
->
Rank
()
>
currentLine
->
Rank
()
)
if
(
!
ni
->
OfKind
(
PNS_ITEM
::
SOLID
)
&&
ni
->
Rank
()
>=
0
&&
ni
->
Rank
()
>
currentLine
->
Rank
()
)
{
switch
(
ni
->
Kind
()
)
{
case
PNS_ITEM
:
:
VIA
:
{
PNS_VIA
*
revVia
=
(
PNS_VIA
*
)
ni
;
PNS_VIA
*
revVia
=
(
PNS_VIA
*
)
ni
;
TRACE
(
2
,
"iter %d: reverse-collide-via"
,
aIter
);
if
(
currentLine
->
EndsWithVia
()
&&
m_currentNode
->
CheckColliding
(
&
currentLine
->
Via
(),
revVia
)
)
if
(
currentLine
->
EndsWithVia
()
&&
m_currentNode
->
CheckColliding
(
&
currentLine
->
Via
(),
revVia
)
)
{
st
=
SH_INCOMPLETE
;
}
else
{
}
else
{
st
=
onReverseCollidingVia
(
currentLine
,
revVia
);
}
...
...
@@ -772,35 +802,37 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
case
PNS_ITEM
:
:
SEGMENT
:
{
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
ni
;
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
ni
;
TRACE
(
2
,
"iter %d: reverse-collide-segment "
,
aIter
);
PNS_LINE
*
revLine
=
assembleLine
(
seg
);
PNS_LINE
*
revLine
=
assembleLine
(
seg
);
popLine
();
st
=
onCollidingLine
(
revLine
,
currentLine
);
pushLine
(
revLine
);
pushLine
(
revLine
);
break
;
}
default
:
assert
(
false
);
assert
(
false
);
}
}
else
{
// "forward" collisoins
}
else
{
// "forward" collisoins
switch
(
ni
->
Kind
()
)
{
case
PNS_ITEM
:
:
SEGMENT
:
TRACE
(
2
,
"iter %d: collide-segment "
,
aIter
);
st
=
onCollidingSegment
(
currentLine
,
(
PNS_SEGMENT
*
)
ni
);
st
=
onCollidingSegment
(
currentLine
,
(
PNS_SEGMENT
*
)
ni
);
break
;
case
PNS_ITEM
:
:
VIA
:
TRACE
(
2
,
"iter %d: shove-via "
,
aIter
);
st
=
onCollidingVia
(
currentLine
,
(
PNS_VIA
*
)
ni
);
st
=
onCollidingVia
(
currentLine
,
(
PNS_VIA
*
)
ni
);
break
;
case
PNS_ITEM
:
:
SOLID
:
TRACE
(
2
,
"iter %d: walk-solid "
,
aIter
);
st
=
onCollidingSolid
(
currentLine
,
(
PNS_SOLID
*
)
ni
);
st
=
onCollidingSolid
(
currentLine
,
(
PNS_SOLID
*
)
ni
);
break
;
default
:
...
...
@@ -811,9 +843,10 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
return
st
;
}
PNS_SHOVE
::
ShoveStatus
PNS_SHOVE
::
shoveMainLoop
()
PNS_SHOVE
::
SHOVE_STATUS
PNS_SHOVE
::
shoveMainLoop
()
{
S
hoveStatus
st
=
SH_OK
;
S
HOVE_STATUS
st
=
SH_OK
;
TRACE
(
1
,
"ShoveStart [root: %d jts, current: %d jts]"
,
m_root
->
JointCount
()
%
m_currentNode
->
JointCount
()
);
...
...
@@ -827,7 +860,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveMainLoop()
while
(
!
m_lineStack
.
empty
()
)
{
st
=
shoveIteration
(
m_iter
);
st
=
shoveIteration
(
m_iter
);
m_iter
++
;
...
...
@@ -842,37 +875,37 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveMainLoop()
}
PNS_SHOVE
::
S
hoveStatus
PNS_SHOVE
::
ShoveLines
(
const
PNS_LINE
&
aCurrentHead
)
PNS_SHOVE
::
S
HOVE_STATUS
PNS_SHOVE
::
ShoveLines
(
const
PNS_LINE
&
aCurrentHead
)
{
S
hoveStatus
st
=
SH_OK
;
S
HOVE_STATUS
st
=
SH_OK
;
// empty head? nothing to shove...
if
(
!
aCurrentHead
.
SegmentCount
()
)
if
(
!
aCurrentHead
.
SegmentCount
()
)
return
SH_INCOMPLETE
;
PNS_LINE
*
head
=
cloneLine
(
&
aCurrentHead
);
PNS_LINE
*
head
=
cloneLine
(
&
aCurrentHead
);
head
->
ClearSegmentLinks
();
m_lineStack
.
clear
();
m_optimizerQueue
.
clear
();
m_newHead
=
O
ptLine
();
m_newHead
=
O
PT_LINE
();
m_logger
.
Clear
();
PNS_ITEMSET
headSet
(
cloneLine
(
&
aCurrentHead
)
);
PNS_ITEMSET
headSet
(
cloneLine
(
&
aCurrentHead
)
);
reduceSpringback
(
headSet
);
PNS_NODE
*
parent
=
m_nodeStack
.
empty
()
?
m_root
:
m_nodeStack
.
back
().
node
;
PNS_NODE
*
parent
=
m_nodeStack
.
empty
()
?
m_root
:
m_nodeStack
.
back
().
m_
node
;
m_currentNode
=
parent
->
Branch
();
m_currentNode
->
ClearRanks
();
m_currentNode
->
Add
(
head
);
head
->
Mark
(
MK_HEAD
);
head
->
SetRank
(
100000
);
head
->
Mark
(
MK_HEAD
);
head
->
SetRank
(
100000
);
m_logger
.
NewGroup
(
"initial"
,
0
);
m_logger
.
Log
(
head
,
0
,
"head"
);
m_logger
.
NewGroup
(
"initial"
,
0
);
m_logger
.
Log
(
head
,
0
,
"head"
);
PNS_VIA
*
headVia
=
NULL
;
...
...
@@ -881,24 +914,24 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
headVia
=
head
->
Via
().
Clone
();
m_currentNode
->
Add
(
headVia
);
headVia
->
Mark
(
MK_HEAD
);
headVia
->
SetRank
(
100000
);
m_logger
.
Log
(
headVia
,
0
,
"head-via"
);
headVia
->
SetRank
(
100000
);
m_logger
.
Log
(
headVia
,
0
,
"head-via"
);
}
pushLine
(
head
);
pushLine
(
head
);
st
=
shoveMainLoop
();
runOptimizer
(
m_currentNode
,
head
);
runOptimizer
(
m_currentNode
,
head
);
if
(
m_newHead
&&
st
==
SH_OK
)
{
st
=
SH_HEAD_MODIFIED
;
Router
()
->
DisplayDebugLine
(
m_newHead
->
CLine
(),
3
,
20000
);
Router
()
->
DisplayDebugLine
(
m_newHead
->
CLine
(),
3
,
20000
);
}
m_currentNode
->
RemoveByMarker
(
MK_HEAD
);
m_currentNode
->
RemoveByMarker
(
MK_HEAD
);
TRACE
(
1
,
"Shove status : %s after %d iterations"
,
((
st
==
SH_OK
||
st
==
SH_HEAD_MODIFIED
)
?
"OK"
:
"FAILURE"
)
%
m_iter
);
TRACE
(
1
,
"Shove status : %s after %d iterations"
,
(
(
st
==
SH_OK
||
st
==
SH_HEAD_MODIFIED
)
?
"OK"
:
"FAILURE"
)
%
m_iter
);
if
(
st
==
SH_OK
||
st
==
SH_HEAD_MODIFIED
)
{
...
...
@@ -909,34 +942,34 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
delete
m_currentNode
;
m_currentNode
=
parent
;
m_newHead
=
O
ptLine
();
m_newHead
=
O
PT_LINE
();
}
return
st
;
}
PNS_SHOVE
::
ShoveStatus
PNS_SHOVE
::
ShoveDraggingVia
(
PNS_VIA
*
aVia
,
const
VECTOR2I
&
aWhere
,
PNS_VIA
**
aNewVia
)
PNS_SHOVE
::
SHOVE_STATUS
PNS_SHOVE
::
ShoveDraggingVia
(
PNS_VIA
*
aVia
,
const
VECTOR2I
&
aWhere
,
PNS_VIA
**
aNewVia
)
{
S
hoveStatus
st
=
SH_OK
;
S
HOVE_STATUS
st
=
SH_OK
;
m_lineStack
.
clear
();
m_optimizerQueue
.
clear
();
m_newHead
=
O
ptLine
();
m_newHead
=
O
PT_LINE
();
m_draggedVia
=
NULL
;
//reduceSpringback( aCurrentHead );
PNS_NODE
*
parent
=
m_nodeStack
.
empty
()
?
m_root
:
m_nodeStack
.
back
().
node
;
PNS_NODE
*
parent
=
m_nodeStack
.
empty
()
?
m_root
:
m_nodeStack
.
back
().
m_
node
;
m_currentNode
=
parent
->
Branch
();
m_currentNode
->
ClearRanks
();
aVia
->
Mark
(
MK_HEAD
);
st
=
pushVia
(
aVia
,
(
aWhere
-
aVia
->
Pos
()),
0
);
st
=
pushVia
(
aVia
,
(
aWhere
-
aVia
->
Pos
()
),
0
);
st
=
shoveMainLoop
();
runOptimizer
(
m_currentNode
,
NULL
);
runOptimizer
(
m_currentNode
,
NULL
);
if
(
st
==
SH_OK
||
st
==
SH_HEAD_MODIFIED
)
{
...
...
@@ -948,64 +981,69 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveDraggingVia ( PNS_VIA *aVia, const VECTOR
m_currentNode
=
parent
;
}
if
(
aNewVia
)
if
(
aNewVia
)
*
aNewVia
=
m_draggedVia
;
return
st
;
}
void
PNS_SHOVE
::
runOptimizer
(
PNS_NODE
*
node
,
PNS_LINE
*
head
)
void
PNS_SHOVE
::
runOptimizer
(
PNS_NODE
*
aNode
,
PNS_LINE
*
aHead
)
{
PNS_OPTIMIZER
optimizer
(
node
);
PNS_OPTIMIZER
optimizer
(
aNode
);
int
optFlags
=
0
,
n_passes
=
0
,
extend
=
0
;
PNS_OPTIMIZATION_EFFORT
effort
=
Settings
().
OptimizerEffort
();
switch
(
effort
)
switch
(
effort
)
{
case
OE_L
ow
:
case
OE_L
OW
:
optFlags
=
PNS_OPTIMIZER
::
MERGE_OBTUSE
;
n_passes
=
1
;
extend
=
0
;
break
;
case
OE_Medium
:
case
OE_MEDIUM
:
optFlags
=
PNS_OPTIMIZER
::
MERGE_OBTUSE
;
n_passes
=
2
;
extend
=
1
;
break
;
case
OE_Full
:
case
OE_FULL
:
optFlags
=
PNS_OPTIMIZER
::
MERGE_SEGMENTS
;
n_passes
=
2
;
break
;
default
:
break
;
}
if
(
Settings
().
SmartPads
())
if
(
Settings
().
SmartPads
()
)
optFlags
|=
PNS_OPTIMIZER
::
SMART_PADS
;
optimizer
.
SetEffortLevel
(
optFlags
);
optimizer
.
SetCollisionMask
(
PNS_ITEM
::
ANY
);
for
(
int
pass
=
0
;
pass
<
n_passes
;
pass
++
)
for
(
int
pass
=
0
;
pass
<
n_passes
;
pass
++
)
{
std
::
reverse
(
m_optimizerQueue
.
begin
(),
m_optimizerQueue
.
end
()
);
for
(
std
::
vector
<
PNS_LINE
*>::
iterator
i
=
m_optimizerQueue
.
begin
();
i
!=
m_optimizerQueue
.
end
();
++
i
)
std
::
reverse
(
m_optimizerQueue
.
begin
(),
m_optimizerQueue
.
end
()
);
for
(
std
::
vector
<
PNS_LINE
*>::
iterator
i
=
m_optimizerQueue
.
begin
();
i
!=
m_optimizerQueue
.
end
();
++
i
)
{
PNS_LINE
*
line
=
*
i
;
PNS_LINE
*
line
=
*
i
;
if
(
!
(
line
->
Marker
()
&
MK_HEAD
)
)
if
(
!
(
line
->
Marker
()
&
MK_HEAD
)
)
{
if
(
effort
==
OE_Medium
||
effort
==
OE_Low
)
if
(
effort
==
OE_MEDIUM
||
effort
==
OE_LOW
)
{
RANGE
<
int
>
r
=
findShovedVertexRange
(
line
);
RANGE
<
int
>
r
=
findShovedVertexRange
(
line
);
if
(
r
.
Defined
()
)
if
(
r
.
Defined
()
)
{
int
start_v
=
std
::
max
(
0
,
r
.
MinV
()
-
extend
);
int
end_v
=
std
::
min
(
line
->
PointCount
()
-
1
,
r
.
MaxV
()
+
extend
);
line
->
ClipVertexRange
(
start_v
,
end_v
);
int
start_v
=
std
::
max
(
0
,
r
.
MinV
()
-
extend
);
int
end_v
=
std
::
min
(
line
->
PointCount
()
-
1
,
r
.
MaxV
()
+
extend
);
line
->
ClipVertexRange
(
start_v
,
end_v
);
}
}
...
...
@@ -1013,9 +1051,9 @@ void PNS_SHOVE::runOptimizer ( PNS_NODE *node, PNS_LINE *head )
if
(
optimizer
.
Optimize
(
line
,
&
optimized
)
)
{
n
ode
->
Remove
(
line
);
line
->
SetShape
(
optimized
.
CLine
()
);
n
ode
->
Add
(
line
);
aN
ode
->
Remove
(
line
);
line
->
SetShape
(
optimized
.
CLine
()
);
aN
ode
->
Add
(
line
);
}
}
}
...
...
@@ -1024,23 +1062,24 @@ void PNS_SHOVE::runOptimizer ( PNS_NODE *node, PNS_LINE *head )
}
const
RANGE
<
int
>
PNS_SHOVE
::
findShovedVertexRange
(
PNS_LINE
*
l
)
const
RANGE
<
int
>
PNS_SHOVE
::
findShovedVertexRange
(
PNS_LINE
*
aL
)
{
RANGE
<
int
>
r
;
for
(
int
i
=
0
;
i
<
l
->
SegmentCount
();
i
++
)
for
(
int
i
=
0
;
i
<
aL
->
SegmentCount
();
i
++
)
{
PNS_SEGMENT
*
s
=
(
*
l
->
LinkedSegments
())[
i
];
PNS_JOINT
*
jt
=
m_root
->
FindJoint
(
s
->
Seg
().
A
,
s
->
Layer
(),
s
->
Net
()
);
PNS_SEGMENT
*
s
=
(
*
aL
->
LinkedSegments
())[
i
];
PNS_JOINT
*
jt
=
m_root
->
FindJoint
(
s
->
Seg
().
A
,
s
->
Layer
(),
s
->
Net
()
);
bool
found
=
false
;
if
(
jt
)
if
(
jt
)
{
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jt
->
LinkList
()
)
BOOST_FOREACH
(
PNS_ITEM
*
item
,
jt
->
LinkList
()
)
{
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
)
if
(
item
->
OfKind
(
PNS_ITEM
::
SEGMENT
)
)
{
PNS_SEGMENT
*
s_old
=
(
PNS_SEGMENT
*
)
item
;
PNS_SEGMENT
*
s_old
=
(
PNS_SEGMENT
*
)
item
;
if
(
s_old
->
Net
()
==
s
->
Net
()
&&
s_old
->
Layer
()
==
s
->
Layer
()
&&
...
...
@@ -1054,27 +1093,31 @@ const RANGE<int> PNS_SHOVE::findShovedVertexRange ( PNS_LINE *l )
}
}
if
(
!
found
)
if
(
!
found
)
{
r
.
Grow
(
i
);
r
.
Grow
(
i
+
1
);
r
.
Grow
(
i
);
r
.
Grow
(
i
+
1
);
}
}
return
r
;
}
PNS_NODE
*
PNS_SHOVE
::
CurrentNode
()
{
return
m_nodeStack
.
empty
()
?
m_root
:
m_nodeStack
.
back
().
node
;
return
m_nodeStack
.
empty
()
?
m_root
:
m_nodeStack
.
back
().
m_
node
;
}
const
PNS_LINE
PNS_SHOVE
::
NewHead
()
const
{
assert
(
m_newHead
);
assert
(
m_newHead
);
return
*
m_newHead
;
}
void
PNS_SHOVE
::
SetInitialLine
(
PNS_LINE
*
aInitial
)
void
PNS_SHOVE
::
SetInitialLine
(
PNS_LINE
*
aInitial
)
{
m_root
=
m_root
->
Branch
();
m_root
->
Remove
(
aInitial
);
...
...
pcbnew/router/pns_shove.h
View file @
ad1b138f
...
...
@@ -44,7 +44,7 @@ class PNS_SHOVE : public PNS_ALGO_BASE
{
public
:
enum
S
hoveStatus
enum
S
HOVE_STATUS
{
SH_OK
=
0
,
SH_NULL
,
...
...
@@ -52,72 +52,74 @@ public:
SH_HEAD_MODIFIED
};
PNS_SHOVE
(
PNS_NODE
*
aWorld
,
PNS_ROUTER
*
aRouter
);
PNS_SHOVE
(
PNS_NODE
*
aWorld
,
PNS_ROUTER
*
aRouter
);
~
PNS_SHOVE
();
virtual
PNS_LOGGER
*
Logger
()
virtual
PNS_LOGGER
*
Logger
()
{
return
&
m_logger
;
}
S
hoveStatus
ShoveLines
(
const
PNS_LINE
&
aCurrentHead
);
S
hoveStatus
ShoveDraggingVia
(
PNS_VIA
*
aVia
,
const
VECTOR2I
&
aWhere
,
PNS_VIA
**
aNewVia
);
S
HOVE_STATUS
ShoveLines
(
const
PNS_LINE
&
aCurrentHead
);
S
HOVE_STATUS
ShoveDraggingVia
(
PNS_VIA
*
aVia
,
const
VECTOR2I
&
aWhere
,
PNS_VIA
**
aNewVia
);
PNS_NODE
*
CurrentNode
();
const
PNS_LINE
NewHead
()
const
;
void
SetInitialLine
(
PNS_LINE
*
aInitial
);
void
SetInitialLine
(
PNS_LINE
*
aInitial
);
private
:
typedef
std
::
vector
<
SHAPE_LINE_CHAIN
>
H
ullSet
;
typedef
boost
::
optional
<
PNS_LINE
>
O
ptLine
;
typedef
std
::
pair
<
PNS_LINE
*
,
PNS_LINE
*>
LinePair
;
typedef
std
::
vector
<
L
inePair
>
LinePairVec
;
typedef
std
::
vector
<
SHAPE_LINE_CHAIN
>
H
ULL_SET
;
typedef
boost
::
optional
<
PNS_LINE
>
O
PT_LINE
;
typedef
std
::
pair
<
PNS_LINE
*
,
PNS_LINE
*>
LINE_PAIR
;
typedef
std
::
vector
<
L
INE_PAIR
>
LINE_PAIR_VEC
;
struct
S
pringbackTag
struct
S
PRINGBACK_TAG
{
int64_t
length
;
int
segments
;
VECTOR2I
p
;
PNS_NODE
*
node
;
PNS_ITEMSET
headItems
;
PNS_COST_ESTIMATOR
cost
;
int64_t
m_
length
;
int
m_
segments
;
VECTOR2I
m_
p
;
PNS_NODE
*
m_
node
;
PNS_ITEMSET
m_
headItems
;
PNS_COST_ESTIMATOR
m_
cost
;
};
ShoveStatus
processSingleLine
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
);
ShoveStatus
processHullSet
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
,
const
HullSet
&
hulls
);
SHOVE_STATUS
processSingleLine
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
);
SHOVE_STATUS
processHullSet
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
,
const
HULL_SET
&
hulls
);
bool
reduceSpringback
(
const
PNS_ITEMSET
&
aHeadItems
);
bool
pushSpringback
(
PNS_NODE
*
aNode
,
const
PNS_ITEMSET
&
aHeadItems
,
const
PNS_COST_ESTIMATOR
&
aCost
);
bool
reduceSpringback
(
const
PNS_ITEMSET
&
aHeadItems
);
bool
pushSpringback
(
PNS_NODE
*
aNode
,
const
PNS_ITEMSET
&
aHeadItems
,
const
PNS_COST_ESTIMATOR
&
aCost
);
S
hoveStatus
walkaroundLoneVia
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
);
bool
checkBumpDirection
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aShoved
)
const
;
S
HOVE_STATUS
walkaroundLoneVia
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
,
PNS_LINE
*
aShoved
);
bool
checkBumpDirection
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aShoved
)
const
;
S
hoveStatus
onCollidingLine
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
);
S
hoveStatus
onCollidingSegment
(
PNS_LINE
*
aCurrent
,
PNS_SEGMENT
*
aObstacleSeg
);
S
hoveStatus
onCollidingSolid
(
PNS_LINE
*
aCurrent
,
PNS_SOLID
*
aObstacleSolid
);
S
hoveStatus
onCollidingVia
(
PNS_ITEM
*
aCurrent
,
PNS_VIA
*
aObstacleVia
);
S
hoveStatus
onReverseCollidingVia
(
PNS_LINE
*
aCurrent
,
PNS_VIA
*
aObstacleVia
);
S
hoveStatus
pushVia
(
PNS_VIA
*
aVia
,
const
VECTOR2I
&
aForce
,
int
aCurrentRank
);
S
HOVE_STATUS
onCollidingLine
(
PNS_LINE
*
aCurrent
,
PNS_LINE
*
aObstacle
);
S
HOVE_STATUS
onCollidingSegment
(
PNS_LINE
*
aCurrent
,
PNS_SEGMENT
*
aObstacleSeg
);
S
HOVE_STATUS
onCollidingSolid
(
PNS_LINE
*
aCurrent
,
PNS_SOLID
*
aObstacleSolid
);
S
HOVE_STATUS
onCollidingVia
(
PNS_ITEM
*
aCurrent
,
PNS_VIA
*
aObstacleVia
);
S
HOVE_STATUS
onReverseCollidingVia
(
PNS_LINE
*
aCurrent
,
PNS_VIA
*
aObstacleVia
);
S
HOVE_STATUS
pushVia
(
PNS_VIA
*
aVia
,
const
VECTOR2I
&
aForce
,
int
aCurrentRank
);
void
unwindStack
(
PNS_SEGMENT
*
s
eg
);
void
unwindStack
(
PNS_ITEM
*
i
tem
);
void
unwindStack
(
PNS_SEGMENT
*
aS
eg
);
void
unwindStack
(
PNS_ITEM
*
aI
tem
);
void
runOptimizer
(
PNS_NODE
*
node
,
PNS_LINE
*
h
ead
);
void
runOptimizer
(
PNS_NODE
*
aNode
,
PNS_LINE
*
aH
ead
);
void
pushLine
(
PNS_LINE
*
l
);
void
pushLine
(
PNS_LINE
*
aL
);
void
popLine
();
const
RANGE
<
int
>
findShovedVertexRange
(
PNS_LINE
*
l
);
const
RANGE
<
int
>
findShovedVertexRange
(
PNS_LINE
*
aL
);
PNS_LINE
*
assembleLine
(
const
PNS_SEGMENT
*
aSeg
,
int
*
aIndex
=
NULL
);
PNS_LINE
*
cloneLine
(
const
PNS_LINE
*
aLine
);
PNS_LINE
*
assembleLine
(
const
PNS_SEGMENT
*
aSeg
,
int
*
aIndex
=
NULL
);
PNS_LINE
*
cloneLine
(
const
PNS_LINE
*
aLine
);
S
hoveStatus
shoveIteration
(
int
aIter
);
S
hoveStatus
shoveMainLoop
();
S
HOVE_STATUS
shoveIteration
(
int
aIter
);
S
HOVE_STATUS
shoveMainLoop
();
std
::
vector
<
S
pringbackTag
>
m_nodeStack
;
std
::
vector
<
S
PRINGBACK_TAG
>
m_nodeStack
;
std
::
vector
<
PNS_LINE
*>
m_lineStack
;
std
::
vector
<
PNS_LINE
*>
m_optimizerQueue
;
std
::
vector
<
PNS_ITEM
*>
m_gcItems
;
...
...
@@ -127,7 +129,7 @@ private:
PNS_LINE
*
m_currentHead
;
PNS_LINE
*
m_collidingLine
;
O
ptLine
m_newHead
;
O
PT_LINE
m_newHead
;
PNS_LOGGER
m_logger
;
PNS_VIA
*
m_draggedVia
;
...
...
pcbnew/router/pns_solid.cpp
View file @
ad1b138f
...
...
@@ -37,8 +37,7 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
case
SH_RECT
:
{
SHAPE_RECT
*
rect
=
static_cast
<
SHAPE_RECT
*>
(
m_shape
);
return
OctagonalHull
(
rect
->
GetPosition
(),
rect
->
GetSize
(),
cl
+
1
,
0.2
*
cl
);
return
OctagonalHull
(
rect
->
GetPosition
(),
rect
->
GetSize
(),
cl
+
1
,
0.2
*
cl
);
}
case
SH_CIRCLE
:
...
...
@@ -46,12 +45,13 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
SHAPE_CIRCLE
*
circle
=
static_cast
<
SHAPE_CIRCLE
*>
(
m_shape
);
int
r
=
circle
->
GetRadius
();
return
OctagonalHull
(
circle
->
GetCenter
()
-
VECTOR2I
(
r
,
r
),
VECTOR2I
(
2
*
r
,
2
*
r
),
cl
+
1
,
0.52
*
(
r
+
cl
)
);
cl
+
1
,
0.52
*
(
r
+
cl
)
);
}
case
SH_SEGMENT
:
{
SHAPE_SEGMENT
*
seg
=
static_cast
<
SHAPE_SEGMENT
*>
(
m_shape
);
return
SegmentHull
(
*
seg
,
aClearance
,
aWalkaroundThickness
);
SHAPE_SEGMENT
*
seg
=
static_cast
<
SHAPE_SEGMENT
*>
(
m_shape
);
return
SegmentHull
(
*
seg
,
aClearance
,
aWalkaroundThickness
);
}
default
:
...
...
@@ -64,6 +64,6 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
PNS_ITEM
*
PNS_SOLID
::
Clone
(
)
const
{
PNS_ITEM
*
solid
=
new
PNS_SOLID
(
*
this
);
PNS_ITEM
*
solid
=
new
PNS_SOLID
(
*
this
);
return
solid
;
}
pcbnew/router/pns_solid.h
View file @
ad1b138f
...
...
@@ -49,7 +49,7 @@ public:
m_pos
=
aSolid
.
m_pos
;
}
PNS_ITEM
*
Clone
(
)
const
;
PNS_ITEM
*
Clone
()
const
;
const
SHAPE
*
Shape
()
const
{
return
m_shape
;
}
...
...
@@ -73,7 +73,7 @@ public:
m_pos
=
aCenter
;
}
virtual
VECTOR2I
Anchor
(
int
n
)
const
virtual
VECTOR2I
Anchor
(
int
aN
)
const
{
return
m_pos
;
}
...
...
@@ -83,7 +83,6 @@ public:
return
1
;
}
private
:
VECTOR2I
m_pos
;
SHAPE
*
m_shape
;
...
...
pcbnew/router/pns_utils.cpp
View file @
ad1b138f
...
...
@@ -24,10 +24,8 @@
#include <geometry/shape_segment.h>
const
SHAPE_LINE_CHAIN
OctagonalHull
(
const
VECTOR2I
&
aP0
,
const
VECTOR2I
&
aSize
,
int
aClearance
,
int
aChamfer
)
const
SHAPE_LINE_CHAIN
OctagonalHull
(
const
VECTOR2I
&
aP0
,
const
VECTOR2I
&
aSize
,
int
aClearance
,
int
aChamfer
)
{
SHAPE_LINE_CHAIN
s
;
...
...
@@ -45,8 +43,8 @@ const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0,
return
s
;
}
const
SHAPE_LINE_CHAIN
SegmentHull
(
const
SHAPE_SEGMENT
&
aSeg
,
int
aClearance
,
const
SHAPE_LINE_CHAIN
SegmentHull
(
const
SHAPE_SEGMENT
&
aSeg
,
int
aClearance
,
int
aWalkaroundThickness
)
{
int
d
=
aSeg
.
GetWidth
()
/
2
+
aClearance
+
aWalkaroundThickness
/
2
+
HULL_MARGIN
;
...
...
@@ -81,14 +79,15 @@ const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg,
return
s
;
}
SHAPE_RECT
ApproximateSegmentAsRect
(
const
SHAPE_SEGMENT
&
aSeg
)
{
SHAPE_RECT
r
;
VECTOR2I
delta
(
aSeg
.
GetWidth
()
/
2
,
aSeg
.
GetWidth
()
/
2
);
VECTOR2I
p0
(
aSeg
.
GetSeg
().
A
-
delta
);
VECTOR2I
p1
(
aSeg
.
GetSeg
().
B
+
delta
);
VECTOR2I
delta
(
aSeg
.
GetWidth
()
/
2
,
aSeg
.
GetWidth
()
/
2
);
VECTOR2I
p0
(
aSeg
.
GetSeg
().
A
-
delta
);
VECTOR2I
p1
(
aSeg
.
GetSeg
().
B
+
delta
);
return
SHAPE_RECT
(
std
::
min
(
p0
.
x
,
p1
.
x
),
std
::
min
(
p0
.
y
,
p1
.
y
),
std
::
abs
(
p1
.
x
-
p0
.
x
),
std
::
abs
(
p1
.
y
-
p0
.
y
)
);
return
SHAPE_RECT
(
std
::
min
(
p0
.
x
,
p1
.
x
),
std
::
min
(
p0
.
y
,
p1
.
y
),
std
::
abs
(
p1
.
x
-
p0
.
x
),
std
::
abs
(
p1
.
y
-
p0
.
y
)
);
}
pcbnew/router/pns_utils.h
View file @
ad1b138f
...
...
@@ -33,8 +33,7 @@
const
SHAPE_LINE_CHAIN
OctagonalHull
(
const
VECTOR2I
&
aP0
,
const
VECTOR2I
&
aSize
,
int
aClearance
,
int
aChamfer
);
const
SHAPE_LINE_CHAIN
SegmentHull
(
const
SHAPE_SEGMENT
&
aSeg
,
int
aClearance
,
const
SHAPE_LINE_CHAIN
SegmentHull
(
const
SHAPE_SEGMENT
&
aSeg
,
int
aClearance
,
int
aWalkaroundThickness
);
SHAPE_RECT
ApproximateSegmentAsRect
(
const
SHAPE_SEGMENT
&
aSeg
);
...
...
pcbnew/router/pns_via.cpp
View file @
ad1b138f
...
...
@@ -25,26 +25,22 @@
#include <geometry/shape_rect.h>
bool
PNS_VIA
::
PushoutForce
(
PNS_NODE
*
aNode
,
const
VECTOR2I
&
aDirection
,
VECTOR2I
&
aForce
,
bool
aSolidsOnly
,
int
aMaxIterations
)
bool
PNS_VIA
::
PushoutForce
(
PNS_NODE
*
aNode
,
const
VECTOR2I
&
aDirection
,
VECTOR2I
&
aForce
,
bool
aSolidsOnly
,
int
aMaxIterations
)
{
int
iter
=
0
;
PNS_VIA
mv
(
*
this
);
VECTOR2I
force
,
totalForce
,
force2
;
while
(
iter
<
aMaxIterations
)
{
PNS_NODE
::
OptObstacle
obs
=
aNode
->
CheckColliding
(
&
mv
,
aSolidsOnly
?
PNS_ITEM
::
SOLID
:
PNS_ITEM
::
ANY
);
PNS_NODE
::
OPT_OBSTACLE
obs
=
aNode
->
CheckColliding
(
&
mv
,
aSolidsOnly
?
PNS_ITEM
::
SOLID
:
PNS_ITEM
::
ANY
);
if
(
!
obs
)
break
;
int
clearance
=
aNode
->
GetClearance
(
obs
->
item
,
&
mv
);
int
clearance
=
aNode
->
GetClearance
(
obs
->
m_
item
,
&
mv
);
if
(
iter
>
aMaxIterations
/
2
)
{
...
...
@@ -53,14 +49,13 @@ bool PNS_VIA::PushoutForce( PNS_NODE* aNode,
mv
.
SetPos
(
mv
.
Pos
()
+
l
);
}
bool
col
=
CollideShapes
(
obs
->
item
->
Shape
(),
mv
.
Shape
(),
clearance
,
true
,
force2
);
bool
col
=
CollideShapes
(
obs
->
m_
item
->
Shape
(),
mv
.
Shape
(),
clearance
,
true
,
force2
);
if
(
col
)
{
if
(
col
)
{
totalForce
+=
force2
;
mv
.
SetPos
(
mv
.
Pos
()
+
force2
);
}
iter
++
;
}
...
...
@@ -68,19 +63,21 @@ bool PNS_VIA::PushoutForce( PNS_NODE* aNode,
return
false
;
aForce
=
totalForce
;
return
true
;
}
const
SHAPE_LINE_CHAIN
PNS_VIA
::
Hull
(
int
aClearance
,
int
aWalkaroundThickness
)
const
{
int
cl
=
(
aClearance
+
aWalkaroundThickness
/
2
);
int
cl
=
(
aClearance
+
aWalkaroundThickness
/
2
);
return
OctagonalHull
(
m_pos
-
VECTOR2I
(
m_diameter
/
2
,
m_diameter
/
2
),
VECTOR2I
(
m_diameter
,
m_diameter
),
cl
+
1
,
(
2
*
cl
+
m_diameter
)
*
0.26
);
VECTOR2I
(
m_diameter
/
2
,
m_diameter
/
2
),
VECTOR2I
(
m_diameter
,
m_diameter
),
cl
+
1
,
(
2
*
cl
+
m_diameter
)
*
0.26
);
}
PNS_VIA
*
PNS_VIA
::
Clone
(
)
const
{
PNS_VIA
*
v
=
new
PNS_VIA
();
...
...
pcbnew/router/pns_via.h
View file @
ad1b138f
...
...
@@ -32,7 +32,8 @@ class PNS_VIA : public PNS_ITEM
{
public
:
PNS_VIA
()
:
PNS_ITEM
(
VIA
)
{};
PNS_ITEM
(
VIA
)
{}
PNS_VIA
(
const
VECTOR2I
&
aPos
,
const
PNS_LAYERSET
&
aLayers
,
int
aDiameter
,
int
aNet
=
-
1
)
:
PNS_ITEM
(
VIA
)
...
...
@@ -42,21 +43,21 @@ public:
m_pos
=
aPos
;
m_diameter
=
aDiameter
;
m_shape
=
SHAPE_CIRCLE
(
aPos
,
aDiameter
/
2
);
}
;
}
PNS_VIA
(
const
PNS_VIA
&
b
)
:
PNS_VIA
(
const
PNS_VIA
&
aB
)
:
PNS_ITEM
(
VIA
)
{
SetNet
(
b
.
Net
()
);
SetLayers
(
b
.
Layers
()
);
m_pos
=
b
.
m_pos
;
m_diameter
=
b
.
m_diameter
;
SetNet
(
aB
.
Net
()
);
SetLayers
(
aB
.
Layers
()
);
m_pos
=
aB
.
m_pos
;
m_diameter
=
aB
.
m_diameter
;
m_shape
=
SHAPE_CIRCLE
(
m_pos
,
m_diameter
/
2
);
m_marker
=
b
.
m_marker
;
m_rank
=
b
.
m_rank
;
m_owner
=
b
.
m_owner
;
m_drill
=
b
.
m_drill
;
m_marker
=
aB
.
m_marker
;
m_rank
=
aB
.
m_rank
;
m_owner
=
aB
.
m_owner
;
m_drill
=
aB
.
m_drill
;
}
const
VECTOR2I
&
Pos
()
const
...
...
@@ -106,7 +107,7 @@ public:
const
SHAPE_LINE_CHAIN
Hull
(
int
aClearance
=
0
,
int
aWalkaroundThickness
=
0
)
const
;
virtual
VECTOR2I
Anchor
(
int
n
)
const
virtual
VECTOR2I
Anchor
(
int
n
)
const
{
return
m_pos
;
}
...
...
@@ -117,7 +118,6 @@ public:
}
private
:
int
m_diameter
;
int
m_drill
;
VECTOR2I
m_pos
;
...
...
pcbnew/router/pns_walkaround.cpp
View file @
ad1b138f
...
...
@@ -32,22 +32,22 @@ using boost::optional;
void
PNS_WALKAROUND
::
start
(
const
PNS_LINE
&
aInitialPath
)
{
m_iteration
=
0
;
m_iteration
_l
imit
=
50
;
m_iteration
L
imit
=
50
;
}
PNS_NODE
::
O
ptObstacle
PNS_WALKAROUND
::
nearestObstacle
(
const
PNS_LINE
&
aPath
)
PNS_NODE
::
O
PT_OBSTACLE
PNS_WALKAROUND
::
nearestObstacle
(
const
PNS_LINE
&
aPath
)
{
return
m_world
->
NearestObstacle
(
&
aPath
,
m_item_mask
);
return
m_world
->
NearestObstacle
(
&
aPath
,
m_itemMask
);
}
PNS_WALKAROUND
::
W
alkaroundStatus
PNS_WALKAROUND
::
singleStep
(
PNS_LINE
&
aPath
,
PNS_WALKAROUND
::
W
ALKAROUND_STATUS
PNS_WALKAROUND
::
singleStep
(
PNS_LINE
&
aPath
,
bool
aWindingDirection
)
{
optional
<
PNS_OBSTACLE
>&
current_obs
=
aWindingDirection
?
m_currentObstacle
[
0
]
:
m_currentObstacle
[
1
];
bool
&
prev_recursive
=
aWindingDirection
?
m_recursiveCollision
[
0
]
:
m_recursiveCollision
[
1
];
if
(
!
current_obs
)
...
...
@@ -55,15 +55,14 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
SHAPE_LINE_CHAIN
path_pre
[
2
],
path_walk
[
2
],
path_post
[
2
];
VECTOR2I
last
=
aPath
.
CPoint
(
-
1
);;
VECTOR2I
last
=
aPath
.
CPoint
(
-
1
);
if
(
(
current_obs
->
hull
).
PointInside
(
last
)
)
if
(
(
current_obs
->
m_
hull
).
PointInside
(
last
)
)
{
m_recursiveBlockageCount
++
;
if
(
m_recursiveBlockageCount
<
3
)
aPath
.
Line
().
Append
(
current_obs
->
hull
.
NearestPoint
(
last
)
);
aPath
.
Line
().
Append
(
current_obs
->
m_
hull
.
NearestPoint
(
last
)
);
else
{
aPath
=
aPath
.
ClipToNearestObstacle
(
m_world
);
...
...
@@ -71,17 +70,18 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
}
}
aPath
.
Walkaround
(
current_obs
->
hull
,
path_pre
[
0
],
path_walk
[
0
],
aPath
.
Walkaround
(
current_obs
->
m_
hull
,
path_pre
[
0
],
path_walk
[
0
],
path_post
[
0
],
aWindingDirection
);
aPath
.
Walkaround
(
current_obs
->
hull
,
path_pre
[
1
],
path_walk
[
1
],
aPath
.
Walkaround
(
current_obs
->
m_
hull
,
path_pre
[
1
],
path_walk
[
1
],
path_post
[
1
],
!
aWindingDirection
);
#ifdef DEBUG
m_logger
.
NewGroup
(
aWindingDirection
?
"walk-cw"
:
"walk-ccw"
,
m_iteration
);
m_logger
.
Log
(
&
path_walk
[
0
],
0
,
"path-walk"
);
m_logger
.
Log
(
&
path_pre
[
0
],
1
,
"path-pre"
);
m_logger
.
Log
(
&
path_post
[
0
],
4
,
"path-post"
);
m_logger
.
Log
(
&
current_obs
->
hull
,
2
,
"hull"
);
m_logger
.
Log
(
current_obs
->
item
,
3
,
"item"
);
m_logger
.
NewGroup
(
aWindingDirection
?
"walk-cw"
:
"walk-ccw"
,
m_iteration
);
m_logger
.
Log
(
&
path_walk
[
0
],
0
,
"path-walk"
);
m_logger
.
Log
(
&
path_pre
[
0
],
1
,
"path-pre"
);
m_logger
.
Log
(
&
path_post
[
0
],
4
,
"path-post"
);
m_logger
.
Log
(
&
current_obs
->
m_hull
,
2
,
"hull"
);
m_logger
.
Log
(
current_obs
->
m_item
,
3
,
"item"
);
#endif
int
len_pre
=
path_walk
[
0
].
Length
();
...
...
@@ -89,8 +89,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
PNS_LINE
walk_path
(
aPath
,
path_walk
[
1
]
);
bool
alt_collides
=
m_world
->
CheckColliding
(
&
walk_path
,
m_item_mask
);
bool
alt_collides
=
m_world
->
CheckColliding
(
&
walk_path
,
m_itemMask
);
SHAPE_LINE_CHAIN
pnew
;
...
...
@@ -127,15 +126,13 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
}
PNS_WALKAROUND
::
WalkaroundStatus
PNS_WALKAROUND
::
Route
(
const
PNS_LINE
&
aInitialPath
,
PNS_LINE
&
aWalkPath
,
bool
aOptimize
)
PNS_WALKAROUND
::
WALKAROUND_STATUS
PNS_WALKAROUND
::
Route
(
const
PNS_LINE
&
aInitialPath
,
PNS_LINE
&
aWalkPath
,
bool
aOptimize
)
{
PNS_LINE
path_cw
(
aInitialPath
),
path_ccw
(
aInitialPath
);
W
alkaroundStatus
s_cw
=
IN_PROGRESS
,
s_ccw
=
IN_PROGRESS
;
W
ALKAROUND_STATUS
s_cw
=
IN_PROGRESS
,
s_ccw
=
IN_PROGRESS
;
SHAPE_LINE_CHAIN
best_path
;
start
(
aInitialPath
);
m_currentObstacle
[
0
]
=
m_currentObstacle
[
1
]
=
nearestObstacle
(
aInitialPath
);
...
...
@@ -143,7 +140,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
aWalkPath
=
aInitialPath
;
while
(
m_iteration
<
m_iteration
_l
imit
)
while
(
m_iteration
<
m_iteration
L
imit
)
{
if
(
s_cw
!=
STUCK
)
s_cw
=
singleStep
(
path_cw
,
true
);
...
...
@@ -156,7 +153,6 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
int
len_cw
=
path_cw
.
CLine
().
Length
();
int
len_ccw
=
path_ccw
.
CLine
().
Length
();
if
(
m_forceLongerPath
)
aWalkPath
=
(
len_cw
>
len_ccw
?
path_cw
:
path_ccw
);
else
...
...
@@ -178,16 +174,15 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
m_iteration
++
;
}
if
(
m_iteration
==
m_iteration
_l
imit
)
if
(
m_iteration
==
m_iteration
L
imit
)
{
int
len_cw
=
path_cw
.
CLine
().
Length
();
int
len_ccw
=
path_ccw
.
CLine
().
Length
();
if
(
m_forceLongerPath
)
aWalkPath
=
(
len_cw
>
len_ccw
?
path_cw
:
path_ccw
);
aWalkPath
=
(
len_cw
>
len_ccw
?
path_cw
:
path_ccw
);
else
aWalkPath
=
(
len_cw
<
len_ccw
?
path_cw
:
path_ccw
);
aWalkPath
=
(
len_cw
<
len_ccw
?
path_cw
:
path_ccw
);
}
if
(
m_cursorApproachMode
)
...
...
@@ -226,16 +221,16 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
aWalkPath
.
Line
().
Simplify
();
if
(
aWalkPath
.
SegmentCount
()
<
1
)
if
(
aWalkPath
.
SegmentCount
()
<
1
)
return
STUCK
;
if
(
aWalkPath
.
CPoint
(
-
1
)
!=
aInitialPath
.
CPoint
(
-
1
)
)
if
(
aWalkPath
.
CPoint
(
-
1
)
!=
aInitialPath
.
CPoint
(
-
1
)
)
return
STUCK
;
if
(
aWalkPath
.
CPoint
(
0
)
!=
aInitialPath
.
CPoint
(
0
)
)
if
(
aWalkPath
.
CPoint
(
0
)
!=
aInitialPath
.
CPoint
(
0
)
)
return
STUCK
;
W
alkaroundStatus
st
=
s_ccw
==
DONE
||
s_cw
==
DONE
?
DONE
:
STUCK
;
W
ALKAROUND_STATUS
st
=
s_ccw
==
DONE
||
s_cw
==
DONE
?
DONE
:
STUCK
;
if
(
aOptimize
&&
st
==
DONE
)
PNS_OPTIMIZER
::
Optimize
(
&
aWalkPath
,
PNS_OPTIMIZER
::
MERGE_OBTUSE
,
m_world
);
...
...
pcbnew/router/pns_walkaround.h
View file @
ad1b138f
...
...
@@ -32,20 +32,20 @@ class PNS_WALKAROUND : public PNS_ALGO_BASE
static
const
int
DefaultIterationLimit
=
50
;
public
:
PNS_WALKAROUND
(
PNS_NODE
*
aWorld
,
PNS_ROUTER
*
aRouter
)
:
PNS_WALKAROUND
(
PNS_NODE
*
aWorld
,
PNS_ROUTER
*
aRouter
)
:
PNS_ALGO_BASE
(
aRouter
),
m_world
(
aWorld
),
m_iteration_l
imit
(
DefaultIterationLimit
)
m_iterationL
imit
(
DefaultIterationLimit
)
{
m_forceSingleDirection
=
false
;
m_forceLongerPath
=
false
;
m_cursorApproachMode
=
false
;
m_item
_m
ask
=
PNS_ITEM
::
ANY
;
}
;
m_item
M
ask
=
PNS_ITEM
::
ANY
;
}
~
PNS_WALKAROUND
()
{};
enum
W
alkaroundStatus
enum
W
ALKAROUND_STATUS
{
IN_PROGRESS
=
0
,
DONE
,
...
...
@@ -59,20 +59,20 @@ public:
void
SetIterationLimit
(
const
int
aIterLimit
)
{
m_iteration
_l
imit
=
aIterLimit
;
m_iteration
L
imit
=
aIterLimit
;
}
void
SetSolidsOnly
(
bool
aSolidsOnly
)
{
if
(
aSolidsOnly
)
m_item
_m
ask
=
PNS_ITEM
::
SOLID
;
if
(
aSolidsOnly
)
m_item
M
ask
=
PNS_ITEM
::
SOLID
;
else
m_item
_m
ask
=
PNS_ITEM
::
ANY
;
m_item
M
ask
=
PNS_ITEM
::
ANY
;
}
void
SetItemMask
(
int
aMask
)
void
SetItemMask
(
int
aMask
)
{
m_item
_m
ask
=
aMask
;
m_item
M
ask
=
aMask
;
}
void
SetSingleDirection
(
bool
aForceSingleDirection
)
...
...
@@ -88,29 +88,30 @@ public:
m_cursorApproachMode
=
aEnabled
;
}
W
alkaroundStatus
Route
(
const
PNS_LINE
&
aInitialPath
,
PNS_LINE
&
aWalkPath
,
W
ALKAROUND_STATUS
Route
(
const
PNS_LINE
&
aInitialPath
,
PNS_LINE
&
aWalkPath
,
bool
aOptimize
=
true
);
virtual
PNS_LOGGER
*
Logger
()
{
virtual
PNS_LOGGER
*
Logger
()
{
return
&
m_logger
;
}
private
:
void
start
(
const
PNS_LINE
&
aInitialPath
);
W
alkaroundStatus
singleStep
(
PNS_LINE
&
aPath
,
bool
aWindingDirection
);
PNS_NODE
::
O
ptObstacle
nearestObstacle
(
const
PNS_LINE
&
aPath
);
W
ALKAROUND_STATUS
singleStep
(
PNS_LINE
&
aPath
,
bool
aWindingDirection
);
PNS_NODE
::
O
PT_OBSTACLE
nearestObstacle
(
const
PNS_LINE
&
aPath
);
PNS_NODE
*
m_world
;
int
m_recursiveBlockageCount
;
int
m_iteration
;
int
m_iteration
_l
imit
;
int
m_item
_m
ask
;
int
m_iteration
L
imit
;
int
m_item
M
ask
;
bool
m_forceSingleDirection
,
m_forceLongerPath
;
bool
m_cursorApproachMode
;
VECTOR2I
m_cursorPos
;
PNS_NODE
::
O
ptObstacle
m_currentObstacle
[
2
];
PNS_NODE
::
O
PT_OBSTACLE
m_currentObstacle
[
2
];
bool
m_recursiveCollision
[
2
];
PNS_LOGGER
m_logger
;
};
...
...
pcbnew/router/range.h
View file @
ad1b138f
...
...
@@ -21,16 +21,17 @@
#ifndef __RANGE_H
#define __RANGE_H
template
<
class
T
>
class
RANGE
{
template
<
class
T
>
class
RANGE
{
public
:
RANGE
(
T
aMin
,
T
aMax
)
:
m_min
(
aMin
),
m_max
(
aMax
),
m_defined
(
true
)
{}
RANGE
(
T
aMin
,
T
aMax
)
:
m_min
(
aMin
),
m_max
(
aMax
),
m_defined
(
true
)
{}
RANGE
()
:
m_defined
(
false
)
{};
RANGE
()
:
m_defined
(
false
)
{}
T
MinV
()
const
{
...
...
@@ -42,36 +43,38 @@ template<class T> class RANGE {
return
m_max
;
}
void
Set
(
T
aMin
,
T
aMax
)
const
void
Set
(
T
aMin
,
T
aMax
)
const
{
m_max
=
aMax
;
m_min
=
aMin
;
}
void
Grow
(
T
value
)
void
Grow
(
T
aValue
)
{
if
(
!
m_defined
)
if
(
!
m_defined
)
{
m_min
=
v
alue
;
m_max
=
v
alue
;
m_min
=
aV
alue
;
m_max
=
aV
alue
;
m_defined
=
true
;
}
else
{
m_min
=
std
::
min
(
m_min
,
value
);
m_max
=
std
::
max
(
m_max
,
value
);
}
else
{
m_min
=
std
::
min
(
m_min
,
aValue
);
m_max
=
std
::
max
(
m_max
,
aValue
);
}
}
bool
Inside
(
const
T
&
v
alue
)
const
bool
Inside
(
const
T
&
aV
alue
)
const
{
if
(
!
m_defined
)
if
(
!
m_defined
)
return
true
;
return
value
>=
m_min
&&
v
alue
<=
m_max
;
return
aValue
>=
m_min
&&
aV
alue
<=
m_max
;
}
bool
Overlaps
(
const
RANGE
<
T
>
&
aOther
)
const
bool
Overlaps
(
const
RANGE
<
T
>
&
aOther
)
const
{
if
(
!
m_defined
||
!
aOther
.
m_defined
)
if
(
!
m_defined
||
!
aOther
.
m_defined
)
return
true
;
return
m_max
>=
aOther
.
m_min
&&
m_min
<=
aOther
.
m_max
;
...
...
@@ -85,7 +88,6 @@ template<class T> class RANGE {
private
:
T
m_min
,
m_max
;
bool
m_defined
;
};
#endif
pcbnew/router/router_preview_item.cpp
View file @
ad1b138f
...
...
@@ -43,7 +43,6 @@ ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem, VIEW_GROUP* aPa
m_clearance
=
-
1
;
m_originLayer
=
m_layer
=
ITEM_GAL_LAYER
(
GP_OVERLAY
);
if
(
aItem
)
Update
(
aItem
);
}
...
...
@@ -56,29 +55,27 @@ ROUTER_PREVIEW_ITEM::~ROUTER_PREVIEW_ITEM()
void
ROUTER_PREVIEW_ITEM
::
Update
(
const
PNS_ITEM
*
aItem
)
{
m_originLayer
=
aItem
->
Layers
().
Start
();
assert
(
m_originLayer
>=
0
);
assert
(
m_originLayer
>=
0
);
m_layer
=
m_originLayer
;
m_color
=
getLayerColor
(
m_originLayer
);
m_color
.
a
=
0.8
;
m_depth
=
BaseOverlayDepth
-
aItem
->
Layers
().
Start
();
m_shape
=
aItem
->
Shape
()
->
Clone
();
switch
(
aItem
->
Kind
()
)
{
case
PNS_ITEM
:
:
LINE
:
m_type
=
PR_SHAPE
;
m_width
=
((
PNS_LINE
*
)
aItem
)
->
Width
();
m_width
=
(
(
PNS_LINE
*
)
aItem
)
->
Width
();
break
;
case
PNS_ITEM
:
:
SEGMENT
:
{
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
aItem
;
PNS_SEGMENT
*
seg
=
(
PNS_SEGMENT
*
)
aItem
;
m_type
=
PR_SHAPE
;
m_width
=
seg
->
Width
();
break
;
...
...
@@ -100,16 +97,17 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
break
;
}
if
(
aItem
->
Marker
()
&
MK_VIOLATION
)
m_color
=
COLOR4D
(
0
,
1
,
0
,
1
);
if
(
aItem
->
Marker
()
&
MK_VIOLATION
)
m_color
=
COLOR4D
(
0
,
1
,
0
,
1
);
if
(
aItem
->
Marker
()
&
MK_HEAD
)
m_color
.
Brighten
(
0.7
);
if
(
aItem
->
Marker
()
&
MK_HEAD
)
m_color
.
Brighten
(
0.7
);
ViewSetVisible
(
true
);
ViewUpdate
(
GEOMETRY
|
APPEARANCE
);
}
const
BOX2I
ROUTER_PREVIEW_ITEM
::
ViewBBox
()
const
{
BOX2I
bbox
;
...
...
@@ -122,7 +120,7 @@ const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
return
bbox
;
case
PR_POINT
:
bbox
=
BOX2I
(
m_pos
-
VECTOR2I
(
100000
,
100000
),
VECTOR2I
(
200000
,
200000
)
);
bbox
=
BOX2I
(
m_pos
-
VECTOR2I
(
100000
,
100000
),
VECTOR2I
(
200000
,
200000
)
);
return
bbox
;
default
:
...
...
@@ -132,20 +130,23 @@ const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
return
bbox
;
}
void
ROUTER_PREVIEW_ITEM
::
drawLineChain
(
const
SHAPE_LINE_CHAIN
&
l
,
KIGFX
::
GAL
*
aGal
)
const
void
ROUTER_PREVIEW_ITEM
::
drawLineChain
(
const
SHAPE_LINE_CHAIN
&
aL
,
KIGFX
::
GAL
*
aGal
)
const
{
for
(
int
s
=
0
;
s
<
l
.
SegmentCount
();
s
++
)
aGal
->
DrawLine
(
l
.
CSegment
(
s
).
A
,
l
.
CSegment
(
s
).
B
);
if
(
l
.
IsClosed
()
)
aGal
->
DrawLine
(
l
.
CSegment
(
-
1
).
B
,
l
.
CSegment
(
0
).
A
);
for
(
int
s
=
0
;
s
<
aL
.
SegmentCount
();
s
++
)
aGal
->
DrawLine
(
aL
.
CSegment
(
s
).
A
,
aL
.
CSegment
(
s
).
B
);
if
(
aL
.
IsClosed
()
)
aGal
->
DrawLine
(
aL
.
CSegment
(
-
1
).
B
,
aL
.
CSegment
(
0
).
A
);
}
void
ROUTER_PREVIEW_ITEM
::
ViewDraw
(
int
aLayer
,
KIGFX
::
GAL
*
aGal
)
const
{
//col.Brighten(0.7);
aGal
->
SetLayerDepth
(
m_depth
);
if
(
m_type
==
PR_SHAPE
)
if
(
m_type
==
PR_SHAPE
)
{
aGal
->
SetLineWidth
(
m_width
);
aGal
->
SetStrokeColor
(
m_color
);
...
...
@@ -153,31 +154,29 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
aGal
->
SetIsStroke
(
m_width
?
true
:
false
);
aGal
->
SetIsFill
(
true
);
if
(
!
m_shape
)
if
(
!
m_shape
)
return
;
switch
(
m_shape
->
Type
()
)
{
case
SH_LINE_CHAIN
:
{
const
SHAPE_LINE_CHAIN
*
l
=
(
const
SHAPE_LINE_CHAIN
*
)
m_shape
;
drawLineChain
(
*
l
,
aGal
);
const
SHAPE_LINE_CHAIN
*
l
=
(
const
SHAPE_LINE_CHAIN
*
)
m_shape
;
drawLineChain
(
*
l
,
aGal
);
break
;
}
case
SH_SEGMENT
:
{
const
SHAPE_SEGMENT
*
s
=
(
const
SHAPE_SEGMENT
*
)
m_shape
;
const
SHAPE_SEGMENT
*
s
=
(
const
SHAPE_SEGMENT
*
)
m_shape
;
aGal
->
DrawLine
(
s
->
GetSeg
().
A
,
s
->
GetSeg
().
B
);
if
(
m_clearance
>
0
)
if
(
m_clearance
>
0
)
{
aGal
->
SetLayerDepth
(
ClearanceOverlayDepth
);
aGal
->
SetStrokeColor
(
COLOR4D
(
DARKDARKGRAY
));
aGal
->
SetLayerDepth
(
ClearanceOverlayDepth
);
aGal
->
SetStrokeColor
(
COLOR4D
(
DARKDARKGRAY
));
aGal
->
SetLineWidth
(
m_width
+
2
*
m_clearance
);
aGal
->
DrawLine
(
s
->
GetSeg
().
A
,
s
->
GetSeg
().
B
);
}
break
;
...
...
@@ -185,13 +184,13 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
case
SH_CIRCLE
:
{
const
SHAPE_CIRCLE
*
c
=
(
const
SHAPE_CIRCLE
*
)
m_shape
;
const
SHAPE_CIRCLE
*
c
=
(
const
SHAPE_CIRCLE
*
)
m_shape
;
aGal
->
DrawCircle
(
c
->
GetCenter
(),
c
->
GetRadius
()
);
if
(
m_clearance
>
0
)
if
(
m_clearance
>
0
)
{
aGal
->
SetLayerDepth
(
ClearanceOverlayDepth
);
aGal
->
SetFillColor
(
COLOR4D
(
DARKDARKGRAY
)
);
aGal
->
SetLayerDepth
(
ClearanceOverlayDepth
);
aGal
->
SetFillColor
(
COLOR4D
(
DARKDARKGRAY
)
);
aGal
->
SetIsStroke
(
false
);
aGal
->
DrawCircle
(
c
->
GetCenter
(),
c
->
GetRadius
()
+
m_clearance
);
}
...
...
@@ -201,20 +200,20 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
case
SH_RECT
:
{
const
SHAPE_RECT
*
r
=
(
const
SHAPE_RECT
*
)
m_shape
;
aGal
->
DrawRectangle
(
r
->
GetPosition
(),
r
->
GetPosition
()
+
r
->
GetSize
()
);
const
SHAPE_RECT
*
r
=
(
const
SHAPE_RECT
*
)
m_shape
;
aGal
->
DrawRectangle
(
r
->
GetPosition
(),
r
->
GetPosition
()
+
r
->
GetSize
()
);
if
(
m_clearance
>
0
)
if
(
m_clearance
>
0
)
{
aGal
->
SetLayerDepth
(
ClearanceOverlayDepth
);
VECTOR2I
p0
(
r
->
GetPosition
()
),
s
(
r
->
GetSize
()
);
aGal
->
SetStrokeColor
(
COLOR4D
(
DARKDARKGRAY
)
);
aGal
->
SetLayerDepth
(
ClearanceOverlayDepth
);
VECTOR2I
p0
(
r
->
GetPosition
()
),
s
(
r
->
GetSize
()
);
aGal
->
SetStrokeColor
(
COLOR4D
(
DARKDARKGRAY
)
);
aGal
->
SetIsStroke
(
true
);
aGal
->
SetLineWidth
(
2
*
m_clearance
);
aGal
->
DrawLine
(
p0
,
VECTOR2I
(
p0
.
x
+
s
.
x
,
p0
.
y
)
);
aGal
->
DrawLine
(
p0
,
VECTOR2I
(
p0
.
x
,
p0
.
y
+
s
.
y
)
);
aGal
->
DrawLine
(
p0
+
s
,
VECTOR2I
(
p0
.
x
+
s
.
x
,
p0
.
y
)
);
aGal
->
DrawLine
(
p0
+
s
,
VECTOR2I
(
p0
.
x
,
p0
.
y
+
s
.
y
)
);
aGal
->
SetLineWidth
(
2
*
m_clearance
);
aGal
->
DrawLine
(
p0
,
VECTOR2I
(
p0
.
x
+
s
.
x
,
p0
.
y
)
);
aGal
->
DrawLine
(
p0
,
VECTOR2I
(
p0
.
x
,
p0
.
y
+
s
.
y
)
);
aGal
->
DrawLine
(
p0
+
s
,
VECTOR2I
(
p0
.
x
+
s
.
x
,
p0
.
y
)
);
aGal
->
DrawLine
(
p0
+
s
,
VECTOR2I
(
p0
.
x
,
p0
.
y
+
s
.
y
)
);
}
break
;
...
...
@@ -226,7 +225,6 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
void
ROUTER_PREVIEW_ITEM
::
Line
(
const
SHAPE_LINE_CHAIN
&
aLine
,
int
aWidth
,
int
aStyle
)
{
m_originLayer
=
m_layer
=
0
;
m_width
=
aWidth
;
m_color
=
assignColor
(
aStyle
);
...
...
@@ -234,15 +232,16 @@ void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int a
m_depth
=
-
2047
;
m_shape
=
aLine
.
Clone
();
ViewSetVisible
(
true
);
ViewSetVisible
(
true
);
ViewUpdate
(
GEOMETRY
|
APPEARANCE
);
}
void
ROUTER_PREVIEW_ITEM
::
Point
(
const
VECTOR2I
&
aPos
,
int
aStyle
)
{
}
void
ROUTER_PREVIEW_ITEM
::
Box
(
const
BOX2I
&
aBox
,
int
aStyle
)
{
}
...
...
@@ -251,7 +250,7 @@ void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle )
const
COLOR4D
ROUTER_PREVIEW_ITEM
::
getLayerColor
(
int
aLayer
)
const
{
PCB_RENDER_SETTINGS
*
settings
=
static_cast
<
PCB_RENDER_SETTINGS
*>
(
m_parent
->
GetView
()
->
GetPainter
()
->
GetSettings
()
);
static_cast
<
PCB_RENDER_SETTINGS
*>
(
m_parent
->
GetView
()
->
GetPainter
()
->
GetSettings
()
);
return
settings
->
GetLayerColor
(
aLayer
);
}
...
...
pcbnew/router/router_preview_item.h
View file @
ad1b138f
...
...
@@ -44,14 +44,13 @@ class PNS_ROUTER;
class
ROUTER_PREVIEW_ITEM
:
public
EDA_ITEM
{
public
:
enum
I
temType
enum
I
TEM_TYPE
{
PR_STUCK_MARKER
=
0
,
PR_POINT
,
PR_SHAPE
};
ROUTER_PREVIEW_ITEM
(
const
PNS_ITEM
*
aItem
=
NULL
,
KIGFX
::
VIEW_GROUP
*
aParent
=
NULL
);
~
ROUTER_PREVIEW_ITEM
();
...
...
@@ -68,12 +67,12 @@ public:
m_color
=
aColor
;
}
void
SetClearance
(
int
aClearance
)
void
SetClearance
(
int
aClearance
)
{
m_clearance
=
aClearance
;
}
void
Show
(
int
a
,
std
::
ostream
&
b
)
const
{};
void
Show
(
int
a
A
,
std
::
ostream
&
aB
)
const
{};
const
BOX2I
ViewBBox
()
const
;
...
...
@@ -85,7 +84,7 @@ public:
aCount
=
1
;
}
void
drawLineChain
(
const
SHAPE_LINE_CHAIN
&
l
,
KIGFX
::
GAL
*
aGal
)
const
;
void
drawLineChain
(
const
SHAPE_LINE_CHAIN
&
aL
,
KIGFX
::
GAL
*
aGal
)
const
;
private
:
const
KIGFX
::
COLOR4D
assignColor
(
int
aStyle
)
const
;
...
...
@@ -94,9 +93,9 @@ private:
KIGFX
::
VIEW_GROUP
*
m_parent
;
PNS_ROUTER
*
m_router
;
SHAPE
*
m_shape
;
SHAPE
*
m_shape
;
I
temType
m_type
;
I
TEM_TYPE
m_type
;
int
m_style
;
int
m_width
;
...
...
pcbnew/router/router_tool.cpp
View file @
ad1b138f
...
...
@@ -82,35 +82,35 @@ ROUTER_TOOL::ROUTER_TOOL() :
m_router
=
NULL
;
}
class
CONTEXT_TRACK_WIDTH_MENU
:
public
CONTEXT_MENU
{
public
:
CONTEXT_TRACK_WIDTH_MENU
()
{
setCustomEventHandler
(
boost
::
bind
(
&
CONTEXT_TRACK_WIDTH_MENU
::
handleCustomEvent
,
this
,
_1
)
);
setCustomEventHandler
(
boost
::
bind
(
&
CONTEXT_TRACK_WIDTH_MENU
::
handleCustomEvent
,
this
,
_1
)
);
}
void
SetBoard
(
BOARD
*
aBoard
)
{
BOARD_DESIGN_SETTINGS
&
bds
=
aBoard
->
GetDesignSettings
();
BOARD_DESIGN_SETTINGS
&
bds
=
aBoard
->
GetDesignSettings
();
wxString
msg
;
m_board
=
aBoard
;
Append
(
ID_POPUP_PCB_SELECT_CUSTOM_WIDTH
,
_
(
"Custom size"
),
wxEmptyString
,
wxITEM_CHECK
);
Append
(
ID_POPUP_PCB_SELECT_CUSTOM_WIDTH
,
_
(
"Custom size"
),
wxEmptyString
,
wxITEM_CHECK
);
Append
(
ID_POPUP_PCB_SELECT_AUTO_WIDTH
,
_
(
"Use the starting track width"
),
_
(
"Route using the width of the starting track."
),
wxITEM_CHECK
);
_
(
"Route using the width of the starting track."
),
wxITEM_CHECK
);
Append
(
ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES
,
_
(
"Use netclass values"
),
_
(
"Use track and via sizes from the net class"
),
wxITEM_CHECK
);
Append
(
ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES
,
_
(
"Use netclass values"
),
_
(
"Use track and via sizes from the net class"
),
wxITEM_CHECK
);
for
(
unsigned
i
=
0
;
i
<
bds
.
m_TrackWidthList
.
size
();
i
++
)
{
msg
=
_
(
"Track "
);
msg
=
_
(
"Track "
);
msg
<<
StringFromValue
(
g_UserUnit
,
bds
.
m_TrackWidthList
[
i
],
true
);
if
(
i
==
0
)
...
...
@@ -123,9 +123,8 @@ public:
for
(
unsigned
i
=
0
;
i
<
bds
.
m_ViasDimensionsList
.
size
();
i
++
)
{
msg
=
_
(
"Via "
);
msg
<<
StringFromValue
(
g_UserUnit
,
bds
.
m_ViasDimensionsList
[
i
].
m_Diameter
,
true
);
msg
=
_
(
"Via "
);
msg
<<
StringFromValue
(
g_UserUnit
,
bds
.
m_ViasDimensionsList
[
i
].
m_Diameter
,
true
);
wxString
drill
=
StringFromValue
(
g_UserUnit
,
bds
.
m_ViasDimensionsList
[
i
].
m_Drill
,
true
);
...
...
@@ -133,7 +132,9 @@ public:
if
(
bds
.
m_ViasDimensionsList
[
i
].
m_Drill
<=
0
)
{
msg
<<
_
(
", drill: default"
);
}
else
{
}
else
{
msg
<<
_
(
", drill: "
)
<<
drill
;
}
...
...
@@ -148,7 +149,7 @@ protected:
OPT_TOOL_EVENT
handleCustomEvent
(
const
wxEvent
&
aEvent
)
{
#if ID_POPUP_PCB_SELECT_VIASIZE1 < ID_POPUP_PCB_SELECT_WIDTH1
#error You have changed event ids
, it breaks a piece of code. Lookup this lin
e for more details.
#error You have changed event ids
order, it breaks code. Check the source cod
e for more details.
// Recognising type of event (track width/via size) is based on comparison if the event id is
// within a specific range. If ranges of event ids changes, then the following is not valid anymore.
#endif
...
...
@@ -156,7 +157,7 @@ protected:
int
id
=
aEvent
.
GetId
();
//
Gener
al settings, to be modified below
//
Initi
al settings, to be modified below
bds
.
m_UseConnectedTrackWidth
=
false
;
bds
.
UseCustomTrackViaSize
(
false
);
...
...
@@ -198,13 +199,10 @@ protected:
};
class
CONTEXT_GRID_MENU
:
public
CONTEXT_MENU
{
};
class
ROUTER_TOOL_MENU
:
public
CONTEXT_MENU
{
class
ROUTER_TOOL_MENU
:
public
CONTEXT_MENU
{
public
:
ROUTER_TOOL_MENU
(
BOARD
*
aBoard
)
ROUTER_TOOL_MENU
(
BOARD
*
aBoard
)
{
SetTitle
(
wxT
(
"Interactive Router"
)
);
Add
(
ACT_NewTrack
);
...
...
@@ -227,6 +225,7 @@ public:
}
};
ROUTER_TOOL
::~
ROUTER_TOOL
()
{
delete
m_router
;
...
...
@@ -259,12 +258,13 @@ int ROUTER_TOOL::getDefaultWidth( int aNetCode )
int
w
,
d1
,
d2
;
getNetclassDimensions
(
aNetCode
,
w
,
d1
,
d2
);
return
w
;
}
void
ROUTER_TOOL
::
getNetclassDimensions
(
int
aNetCode
,
int
&
aWidth
,
int
&
aViaDiameter
,
int
&
aViaDrill
)
int
&
aViaDiameter
,
int
&
aViaDrill
)
{
BOARD
*
board
=
getModel
<
BOARD
>
(
PCB_T
);
BOARD_DESIGN_SETTINGS
&
bds
=
board
->
GetDesignSettings
();
...
...
@@ -316,29 +316,29 @@ PNS_ITEM* ROUTER_TOOL::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLa
{
if
(
!
prioritized
[
2
]
)
prioritized
[
2
]
=
item
;
if
(
item
->
Layers
().
Overlaps
(
tl
))
if
(
item
->
Layers
().
Overlaps
(
tl
)
)
prioritized
[
0
]
=
item
;
}
else
{
if
(
!
prioritized
[
3
]
)
prioritized
[
3
]
=
item
;
if
(
item
->
Layers
().
Overlaps
(
tl
)
)
if
(
item
->
Layers
().
Overlaps
(
tl
)
)
prioritized
[
1
]
=
item
;
}
}
}
PNS_ITEM
*
rv
=
NULL
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
PNS_ITEM
*
rv
=
NULL
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
PNS_ITEM
*
item
=
prioritized
[
i
];
PNS_ITEM
*
item
=
prioritized
[
i
];
if
(
DisplayOpt
.
ContrastModeDisplay
)
if
(
item
&&
!
item
->
Layers
().
Overlaps
(
tl
)
)
item
=
NULL
;
if
(
item
)
if
(
item
)
{
rv
=
item
;
break
;
...
...
@@ -349,12 +349,12 @@ PNS_ITEM* ROUTER_TOOL::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLa
rv
=
NULL
;
if
(
rv
)
TRACE
(
0
,
"%s, layer : %d, tl: %d"
,
rv
->
KindStr
().
c_str
()
%
rv
->
Layers
().
Start
()
%
tl
);
TRACE
(
0
,
"%s, layer : %d, tl: %d"
,
rv
->
KindStr
().
c_str
()
%
rv
->
Layers
().
Start
()
%
tl
);
return
rv
;
}
void
ROUTER_TOOL
::
highlightNet
(
bool
aEnabled
,
int
aNetcode
)
{
RENDER_SETTINGS
*
rs
=
getView
()
->
GetPainter
()
->
GetSettings
();
...
...
@@ -367,22 +367,23 @@ void ROUTER_TOOL::highlightNet( bool aEnabled, int aNetcode )
getView
()
->
UpdateAllLayersColor
();
}
void
ROUTER_TOOL
::
handleCommonEvents
(
TOOL_EVENT
&
evt
)
void
ROUTER_TOOL
::
handleCommonEvents
(
TOOL_EVENT
&
aEvent
)
{
#ifdef DEBUG
if
(
ev
t
.
IsKeyPressed
()
)
if
(
aEven
t
.
IsKeyPressed
()
)
{
switch
(
ev
t
.
KeyCode
()
)
switch
(
aEven
t
.
KeyCode
()
)
{
case
'S'
:
TRACEn
(
2
,
"saving drag/route log...
\n
"
);
TRACEn
(
2
,
"saving drag/route log...
\n
"
);
m_router
->
DumpLog
();
break
;
}
}
else
#endif
if
(
ev
t
.
IsAction
(
&
ACT_RouterOptions
)
)
if
(
aEven
t
.
IsAction
(
&
ACT_RouterOptions
)
)
{
DIALOG_PNS_SETTINGS
settingsDlg
(
m_toolMgr
->
GetEditFrame
(),
m_router
->
Settings
()
);
...
...
@@ -390,7 +391,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
m_router
->
ApplySettings
();
}
else
if
(
ev
t
.
IsAction
(
&
ACT_CustomTrackWidth
)
)
else
if
(
aEven
t
.
IsAction
(
&
ACT_CustomTrackWidth
)
)
{
DIALOG_TRACK_VIA_SIZE
sizeDlg
(
m_toolMgr
->
GetEditFrame
(),
m_router
->
Settings
()
);
BOARD_DESIGN_SETTINGS
&
bds
=
getModel
<
BOARD
>
(
PCB_T
)
->
GetDesignSettings
();
...
...
@@ -410,7 +411,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
handleCommonEvents
(
event
);
}
else
if
(
ev
t
.
IsAction
(
&
COMMON_ACTIONS
::
trackViaSizeChanged
)
)
else
if
(
aEven
t
.
IsAction
(
&
COMMON_ACTIONS
::
trackViaSizeChanged
)
)
{
BOARD_DESIGN_SETTINGS
&
bds
=
getModel
<
BOARD
>
(
PCB_T
)
->
GetDesignSettings
();
...
...
@@ -421,6 +422,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
}
}
void
ROUTER_TOOL
::
updateStartItem
(
TOOL_EVENT
&
aEvent
)
{
VIEW_CONTROLS
*
ctls
=
getViewControls
();
...
...
@@ -431,14 +433,11 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent )
if
(
aEvent
.
IsMotion
()
||
aEvent
.
IsClick
()
)
{
VECTOR2I
p
=
aEvent
.
Position
();
startItem
=
pickSingleItem
(
p
);
bool
snapEnabled
=
!
aEvent
.
Modifier
(
MD_SHIFT
);
m_router
->
EnableSnapping
(
snapEnabled
);
if
(
!
snapEnabled
&&
startItem
&&
!
startItem
->
Layers
().
Overlaps
(
tl
)
)
if
(
!
snapEnabled
&&
startItem
&&
!
startItem
->
Layers
().
Overlaps
(
tl
)
)
startItem
=
NULL
;
if
(
startItem
&&
startItem
->
Net
()
>=
0
)
...
...
@@ -446,10 +445,13 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent )
bool
dummy
;
VECTOR2I
psnap
=
m_router
->
SnapToItem
(
startItem
,
p
,
dummy
);
if
(
snapEnabled
)
{
if
(
snapEnabled
)
{
m_startSnapPoint
=
psnap
;
ctls
->
ForceCursorPosition
(
true
,
psnap
);
}
else
{
}
else
{
m_startSnapPoint
=
cp
;
ctls
->
ForceCursorPosition
(
false
);
}
...
...
@@ -514,8 +516,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent )
}
if
(
m_endItem
)
TRACE
(
0
,
"%s, layer : %d"
,
m_endItem
->
KindStr
().
c_str
()
%
m_endItem
->
Layers
().
Start
()
);
TRACE
(
0
,
"%s, layer : %d"
,
m_endItem
->
KindStr
().
c_str
()
%
m_endItem
->
Layers
().
Start
()
);
}
...
...
@@ -573,7 +574,8 @@ void ROUTER_TOOL::performRouting()
break
;
m_router
->
Move
(
m_endSnapPoint
,
m_endItem
);
}
else
if
(
evt
->
IsAction
(
&
ACT_PlaceThroughVia
)
)
}
else
if
(
evt
->
IsAction
(
&
ACT_PlaceThroughVia
)
)
{
m_router
->
ToggleViaPlacement
();
frame
->
SetTopLayer
(
m_router
->
GetCurrentLayer
()
);
...
...
@@ -636,7 +638,8 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent )
// Deselect all items
m_toolMgr
->
RunAction
(
COMMON_ACTIONS
::
selectionClear
);
getEditFrame
<
PCB_EDIT_FRAME
>
()
->
SetToolID
(
ID_TRACK_BUTT
,
wxCURSOR_PENCIL
,
_
(
"Interactive Router"
)
);
getEditFrame
<
PCB_EDIT_FRAME
>
()
->
SetToolID
(
ID_TRACK_BUTT
,
wxCURSOR_PENCIL
,
_
(
"Interactive Router"
)
);
ctls
->
SetSnapping
(
true
);
ctls
->
ShowCursor
(
true
);
...
...
@@ -700,7 +703,7 @@ void ROUTER_TOOL::performDragging()
bool
dragStarted
=
m_router
->
StartDragging
(
m_startSnapPoint
,
m_startItem
);
if
(
!
dragStarted
)
if
(
!
dragStarted
)
return
;
if
(
m_startItem
&&
m_startItem
->
Net
()
>=
0
)
...
...
@@ -725,12 +728,11 @@ void ROUTER_TOOL::performDragging()
}
else
if
(
evt
->
IsClick
(
BUT_LEFT
)
)
{
if
(
m_router
->
FixRoute
(
m_endSnapPoint
,
m_endItem
)
)
break
;
}
handleCommonEvents
(
*
evt
);
handleCommonEvents
(
*
evt
);
}
if
(
m_router
->
RoutingInProgress
()
)
...
...
pcbnew/router/router_tool.h
View file @
ad1b138f
...
...
@@ -49,7 +49,6 @@ public:
int
Main
(
TOOL_EVENT
&
aEvent
);
private
:
PNS_ITEM
*
pickSingleItem
(
const
VECTOR2I
&
aWhere
,
int
aNet
=
-
1
,
int
aLayer
=
-
1
);
int
getDefaultWidth
(
int
aNetCode
);
...
...
@@ -57,7 +56,7 @@ private:
void
performRouting
();
void
performDragging
();
void
highlightNet
(
bool
enabled
,
int
n
etcode
=
-
1
);
void
highlightNet
(
bool
aEnabled
,
int
aN
etcode
=
-
1
);
void
updateStartItem
(
TOOL_EVENT
&
aEvent
);
void
updateEndItem
(
TOOL_EVENT
&
aEvent
);
...
...
@@ -78,7 +77,6 @@ private:
PNS_ITEM
*
m_endItem
;
VECTOR2I
m_endSnapPoint
;
CONTEXT_MENU
*
m_menu
;
///> Flag marking that the router's world needs syncing.
...
...
pcbnew/router/time_limit.cpp
View file @
ad1b138f
...
...
@@ -24,23 +24,28 @@
TIME_LIMIT
::
TIME_LIMIT
(
int
aMilliseconds
)
:
m_limitMs
(
aMilliseconds
)
{
{
Restart
();
};
}
TIME_LIMIT
::~
TIME_LIMIT
()
{}
TIME_LIMIT
::~
TIME_LIMIT
()
{}
bool
TIME_LIMIT
::
Expired
()
const
{
return
(
wxGetLocalTimeMillis
().
GetValue
()
-
m_startTics
)
>=
m_limitMs
;
}
void
TIME_LIMIT
::
Restart
()
{
m_startTics
=
wxGetLocalTimeMillis
().
GetValue
();
}
void
TIME_LIMIT
::
Set
(
int
aMilliseconds
)
void
TIME_LIMIT
::
Set
(
int
aMilliseconds
)
{
m_limitMs
=
aMilliseconds
;
}
pcbnew/router/time_limit.h
View file @
ad1b138f
...
...
@@ -23,22 +23,20 @@
#include <stdint.h>
class
TIME_LIMIT
{
class
TIME_LIMIT
{
public
:
TIME_LIMIT
(
int
aMilliseconds
=
0
);
~
TIME_LIMIT
();
TIME_LIMIT
(
int
aMilliseconds
=
0
);
~
TIME_LIMIT
();
bool
Expired
()
const
;
void
Restart
();
void
Set
(
int
aMilliseconds
);
void
Set
(
int
aMilliseconds
);
private
:
int
m_limitMs
;
int64_t
m_startTics
;
};
#endif
pcbnew/router/trace.h
View file @
ad1b138f
...
...
@@ -25,10 +25,10 @@
#include <iostream>
#include <boost/format.hpp>
static
inline
void
_trace_print
(
const
char
*
aFuncName
,
int
l
evel
,
const
std
::
string
&
aMsg
)
static
inline
void
_trace_print
(
const
char
*
aFuncName
,
int
aL
evel
,
const
std
::
string
&
aMsg
)
{
#ifdef DEBUG
std
::
cerr
<<
"trace["
<<
l
evel
<<
"]: "
<<
aFuncName
<<
": "
<<
aMsg
<<
std
::
endl
;
std
::
cerr
<<
"trace["
<<
aL
evel
<<
"]: "
<<
aFuncName
<<
": "
<<
aMsg
<<
std
::
endl
;
#endif
}
...
...
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