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
190af5d9
Commit
190af5d9
authored
Mar 09, 2015
by
Maciej Suminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added functions to resolve connectivity queries in ratsnest (GAL).
parent
e6a10faa
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
291 additions
and
123 deletions
+291
-123
hetriang.h
include/ttl/halfedge/hetriang.h
+63
-43
ratsnest_data.cpp
pcbnew/ratsnest_data.cpp
+159
-38
ratsnest_data.h
pcbnew/ratsnest_data.h
+65
-39
ratsnest_viewitem.cpp
pcbnew/ratsnest_viewitem.cpp
+4
-3
No files found.
include/ttl/halfedge/hetriang.h
View file @
190af5d9
...
...
@@ -4,21 +4,21 @@
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
*
* This file is part of TTL.
*
* TTL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
* License, or (at your option) any later version.
*
* TTL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* TTL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
...
...
@@ -36,7 +36,7 @@
* disclosing the source code of your own applications.
*
* This file may be used in accordance with the terms contained in a
* written agreement between you and SINTEF ICT.
* written agreement between you and SINTEF ICT.
*/
#ifndef _HE_TRIANG_H_
...
...
@@ -100,6 +100,9 @@ protected:
/// Node coordinates
int
m_x
,
m_y
;
/// Tag for quick connection resolution
int
m_tag
;
/// Reference count
unsigned
int
m_refCount
;
...
...
@@ -112,7 +115,7 @@ public:
#ifdef TTL_USE_NODE_ID
m_id
(
id_count
++
),
#endif
m_x
(
aX
),
m_y
(
aY
),
m_refCount
(
0
)
m_x
(
aX
),
m_y
(
aY
),
m_
tag
(
-
1
),
m_
refCount
(
0
)
{
}
...
...
@@ -120,20 +123,32 @@ public:
~
NODE
()
{}
/// Returns the x-coordinate
int
GetX
()
const
in
line
in
t
GetX
()
const
{
return
m_x
;
}
/// Returns the y-coordinate
int
GetY
()
const
in
line
in
t
GetY
()
const
{
return
m_y
;
}
/// Returns tag, common identifier for connected nodes
inline
int
GetTag
()
const
{
return
m_tag
;
}
/// Sets tag, common identifier for connected nodes
inline
void
SetTag
(
int
aTag
)
{
m_tag
=
aTag
;
}
#ifdef TTL_USE_NODE_ID
/// Returns the id (TTL_USE_NODE_ID must be defined)
int
Id
()
const
in
line
in
t
Id
()
const
{
return
m_id
;
}
...
...
@@ -141,35 +156,35 @@ public:
#ifdef TTL_USE_NODE_FLAG
/// Sets the flag (TTL_USE_NODE_FLAG must be defined)
void
SetFlag
(
bool
aFlag
)
inline
void
SetFlag
(
bool
aFlag
)
{
m_flag
=
aFlag
;
}
/// Returns the flag (TTL_USE_NODE_FLAG must be defined)
const
bool
&
GetFlag
()
const
inline
const
bool
&
GetFlag
()
const
{
return
m_flag
;
}
#endif
void
IncRefCount
()
inline
void
IncRefCount
()
{
m_refCount
++
;
}
void
DecRefCount
()
inline
void
DecRefCount
()
{
m_refCount
--
;
}
unsigned
int
GetRefCount
()
const
inline
unsigned
int
GetRefCount
()
const
{
return
m_refCount
;
}
};
/**
* \class EDGE
* \brief \b %Edge class in the in the half-edge data structure.
...
...
@@ -187,55 +202,65 @@ public:
{
}
/// Returns tag, common identifier for connected nodes
inline
int
GetTag
()
const
{
int
tag
=
GetSourceNode
()
->
GetTag
();
if
(
tag
>=
0
)
return
tag
;
return
GetTargetNode
()
->
GetTag
();
}
/// Sets the source node
void
SetSourceNode
(
const
NODE_PTR
&
aNode
)
inline
void
SetSourceNode
(
const
NODE_PTR
&
aNode
)
{
m_sourceNode
=
aNode
;
}
/// Sets the next edge in face
void
SetNextEdgeInFace
(
const
EDGE_PTR
&
aEdge
)
inline
void
SetNextEdgeInFace
(
const
EDGE_PTR
&
aEdge
)
{
m_nextEdgeInFace
=
aEdge
;
}
/// Sets the twin edge
void
SetTwinEdge
(
const
EDGE_PTR
&
aEdge
)
inline
void
SetTwinEdge
(
const
EDGE_PTR
&
aEdge
)
{
m_twinEdge
=
aEdge
;
}
/// Sets the edge as a leading edge
void
SetAsLeadingEdge
(
bool
aLeading
=
true
)
inline
void
SetAsLeadingEdge
(
bool
aLeading
=
true
)
{
m_isLeadingEdge
=
aLeading
;
}
/// Checks if an edge is a leading edge
bool
IsLeadingEdge
()
const
inline
bool
IsLeadingEdge
()
const
{
return
m_isLeadingEdge
;
}
/// Returns the twin edge
EDGE_PTR
GetTwinEdge
()
const
inline
EDGE_PTR
GetTwinEdge
()
const
{
return
m_twinEdge
.
lock
();
}
void
ClearTwinEdge
()
inline
void
ClearTwinEdge
()
{
m_twinEdge
.
reset
();
}
/// Returns the next edge in face
const
EDGE_PTR
&
GetNextEdgeInFace
()
const
inline
const
EDGE_PTR
&
GetNextEdgeInFace
()
const
{
return
m_nextEdgeInFace
;
}
/// Retuns the source node
const
NODE_PTR
&
GetSourceNode
()
const
inline
const
NODE_PTR
&
GetSourceNode
()
const
{
return
m_sourceNode
;
}
...
...
@@ -246,12 +271,12 @@ public:
return
m_nextEdgeInFace
->
GetSourceNode
();
}
void
SetWeight
(
unsigned
int
weight
)
inline
void
SetWeight
(
unsigned
int
weight
)
{
m_weight
=
weight
;
}
unsigned
int
GetWeight
()
const
inline
unsigned
int
GetWeight
()
const
{
return
m_weight
;
}
...
...
@@ -294,22 +319,17 @@ public:
m_weight
=
aWeight
;
}
EDGE_MST
(
const
EDGE
&
edge
)
{
m_sourceNode
=
edge
.
GetSourceNode
();
m_target
=
edge
.
GetTargetNode
();
m_weight
=
edge
.
GetWeight
();
}
~
EDGE_MST
()
{
}
/// @copydoc Edge::setSourceNode()
virtual
const
NODE_PTR
&
GetTargetNode
()
const
{
return
m_target
;
}
private
:
EDGE_MST
(
const
EDGE
&
aEdge
)
{
assert
(
false
);
}
};
class
DART
;
// Forward declaration (class in this namespace)
...
...
@@ -410,7 +430,7 @@ public:
/// Swaps the edge associated with diagonal
void
SwapEdge
(
EDGE_PTR
&
aDiagonal
);
/// Splits the triangle associated with edge into three new triangles joining at point
/// Splits the triangle associated with edge into three new triangles joining at point
EDGE_PTR
SplitTriangle
(
EDGE_PTR
&
aEdge
,
const
NODE_PTR
&
aPoint
);
// Functions required by TTL for removing nodes in a Delaunay triangulation
...
...
@@ -440,7 +460,7 @@ public:
std
::
list
<
EDGE_PTR
>*
GetEdges
(
bool
aSkipBoundaryEdges
=
false
)
const
;
#ifdef TTL_USE_NODE_FLAG
/// Sets flag in all the nodes
/// Sets flag in all the nodes
void
FlagNodes
(
bool
aFlag
)
const
;
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
...
...
pcbnew/ratsnest_data.cpp
View file @
190af5d9
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* Copyright (C) 2013
-2015
CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
...
...
@@ -96,22 +96,26 @@ bool isEdgeConnectingNode( const RN_EDGE_PTR& aEdge, const RN_NODE_PTR& aNode )
}
st
d
::
vector
<
RN_EDGE
_PTR
>*
kruskalMST
(
RN_LINKS
::
RN_EDGE_LIST
&
aEdges
,
const
std
::
vector
<
RN_NODE_PTR
>&
aNodes
)
st
atic
std
::
vector
<
RN_EDGE_MST
_PTR
>*
kruskalMST
(
RN_LINKS
::
RN_EDGE_LIST
&
aEdges
,
std
::
vector
<
RN_NODE_PTR
>&
aNodes
)
{
unsigned
int
nodeNumber
=
aNodes
.
size
();
unsigned
int
mstExpectedSize
=
nodeNumber
-
1
;
unsigned
int
mstSize
=
0
;
bool
ratsnestLines
=
false
;
// The output
std
::
vector
<
RN_EDGE_
PTR
>*
mst
=
new
std
::
vector
<
RN_EDGE
_PTR
>
;
std
::
vector
<
RN_EDGE_
MST_PTR
>*
mst
=
new
std
::
vector
<
RN_EDGE_MST
_PTR
>
;
mst
->
reserve
(
mstExpectedSize
);
// Set tags for marking cycles
boost
::
unordered_map
<
RN_NODE_PTR
,
int
>
tags
;
unsigned
int
tag
=
0
;
BOOST_FOREACH
(
const
RN_NODE_PTR
&
node
,
aNodes
)
BOOST_FOREACH
(
RN_NODE_PTR
&
node
,
aNodes
)
{
node
->
SetTag
(
tag
);
tags
[
node
]
=
tag
++
;
}
// Lists of nodes connected together (subtrees) to detect cycles in the graph
std
::
vector
<
std
::
list
<
int
>
>
cycles
(
nodeNumber
);
...
...
@@ -123,27 +127,40 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
while
(
mstSize
<
mstExpectedSize
&&
!
aEdges
.
empty
()
)
{
RN_EDGE_PTR
&
dt
=
*
aEdges
.
begin
();
RN_EDGE_PTR
&
dt
=
aEdges
.
front
();
int
srcTag
=
tags
[
dt
->
GetSourceNode
()];
int
trgTag
=
tags
[
dt
->
GetTargetNode
()];
// Because edges are sorted by their weight, first we always process connected
// items (weight == 0). Once we stumble upon an edge with non-zero weight,
// it means that the rest of the lines are ratsnest.
if
(
!
ratsnestLines
&&
dt
->
GetWeight
()
!=
0
)
ratsnestLines
=
true
;
// Check if by adding this edge we are going to join two different forests
if
(
srcTag
!=
trgTag
)
{
// Update tags
std
::
list
<
int
>::
iterator
it
,
itEnd
;
for
(
it
=
cycles
[
trgTag
].
begin
(),
itEnd
=
cycles
[
trgTag
].
end
();
it
!=
itEnd
;
++
it
)
tags
[
aNodes
[
*
it
]]
=
srcTag
;
// Move nodes that were marked with old tag to the list marked with the new tag
cycles
[
srcTag
].
splice
(
cycles
[
srcTag
].
end
(),
cycles
[
trgTag
]
);
if
(
dt
->
GetWeight
()
==
0
)
// Skip already existing connections (weight == 0
)
if
(
ratsnestLines
)
{
mstExpectedSize
--
;
for
(
it
=
cycles
[
trgTag
].
begin
(),
itEnd
=
cycles
[
trgTag
].
end
();
it
!=
itEnd
;
++
it
)
tags
[
aNodes
[
*
it
]]
=
srcTag
;
}
else
{
for
(
it
=
cycles
[
trgTag
].
begin
(),
itEnd
=
cycles
[
trgTag
].
end
();
it
!=
itEnd
;
++
it
)
{
tags
[
aNodes
[
*
it
]]
=
srcTag
;
aNodes
[
*
it
]
->
SetTag
(
srcTag
);
}
}
// Move nodes that were marked with old tag to the list marked with the new tag
cycles
[
srcTag
].
splice
(
cycles
[
srcTag
].
end
(),
cycles
[
trgTag
]
);
if
(
ratsnestLines
)
{
// Do a copy of edge, but make it RN_EDGE_MST. In contrary to RN_EDGE,
// RN_EDGE_MST saves both source and target node and does not require any other
...
...
@@ -154,6 +171,11 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
mst
->
push_back
(
newEdge
);
++
mstSize
;
}
else
{
// Processing a connection, decrease the expected size of the ratsnest MST
--
mstExpectedSize
;
}
}
// Remove the edge that was just processed
...
...
@@ -167,7 +189,7 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
}
void
RN_NET
::
validateEdge
(
RN_EDGE_PTR
&
aEdge
)
void
RN_NET
::
validateEdge
(
RN_EDGE_
MST_
PTR
&
aEdge
)
{
RN_NODE_PTR
source
=
aEdge
->
GetSourceNode
();
RN_NODE_PTR
target
=
aEdge
->
GetTargetNode
();
...
...
@@ -238,12 +260,13 @@ bool RN_LINKS::RemoveNode( const RN_NODE_PTR& aNode )
}
const
RN_EDGE_PTR
&
RN_LINKS
::
AddConnection
(
const
RN_NODE_PTR
&
aNode1
,
const
RN_NODE_PTR
&
aNode2
,
unsigned
int
aDistance
)
RN_EDGE_MST_PTR
RN_LINKS
::
AddConnection
(
const
RN_NODE_PTR
&
aNode1
,
const
RN_NODE_PTR
&
aNode2
,
unsigned
int
aDistance
)
{
m_edges
.
push_back
(
boost
::
make_shared
<
RN_EDGE_MST
>
(
aNode1
,
aNode2
,
aDistance
)
);
RN_EDGE_MST_PTR
edge
=
boost
::
make_shared
<
RN_EDGE_MST
>
(
aNode1
,
aNode2
,
aDistance
);
m_edges
.
push_back
(
edge
);
return
m_edges
.
back
()
;
return
edge
;
}
...
...
@@ -252,10 +275,10 @@ void RN_NET::compute()
const
RN_LINKS
::
RN_NODE_SET
&
boardNodes
=
m_links
.
GetNodes
();
const
RN_LINKS
::
RN_EDGE_LIST
&
boardEdges
=
m_links
.
GetConnections
();
// Special case that does need so complicated algorithm
if
(
boardNodes
.
size
()
=
=
2
)
// Special case
s
that does need so complicated algorithm
if
(
boardNodes
.
size
()
<
=
2
)
{
m_rnEdges
.
reset
(
new
std
::
vector
<
RN_EDGE_PTR
>
(
0
)
);
m_rnEdges
.
reset
(
new
std
::
vector
<
RN_EDGE_
MST_
PTR
>
(
0
)
);
// Check if the only possible connection exists
if
(
boardEdges
.
size
()
==
0
)
...
...
@@ -268,12 +291,6 @@ void RN_NET::compute()
return
;
}
else
if
(
boardNodes
.
size
()
<=
1
)
// This case is even simpler
{
m_rnEdges
.
reset
(
new
std
::
vector
<
RN_EDGE_PTR
>
(
0
)
);
return
;
}
// Move and sort (sorting speeds up) all nodes to a vector for the Delaunay triangulation
std
::
vector
<
RN_NODE_PTR
>
nodes
(
boardNodes
.
size
()
);
...
...
@@ -301,7 +318,7 @@ void RN_NET::clearNode( const RN_NODE_PTR& aNode )
if
(
!
m_rnEdges
)
return
;
std
::
vector
<
RN_EDGE_PTR
>::
iterator
newEnd
;
std
::
vector
<
RN_EDGE_
MST_
PTR
>::
iterator
newEnd
;
// Remove all ratsnest edges for associated with the node
newEnd
=
std
::
remove_if
(
m_rnEdges
->
begin
(),
m_rnEdges
->
end
(),
...
...
@@ -377,7 +394,7 @@ void RN_NET::Update()
compute
();
BOOST_FOREACH
(
RN_EDGE_PTR
&
edge
,
*
m_rnEdges
)
BOOST_FOREACH
(
RN_EDGE_
MST_
PTR
&
edge
,
*
m_rnEdges
)
validateEdge
(
edge
);
m_dirty
=
false
;
...
...
@@ -386,8 +403,7 @@ void RN_NET::Update()
void
RN_NET
::
AddItem
(
const
D_PAD
*
aPad
)
{
RN_NODE_PTR
nodePtr
=
m_links
.
AddNode
(
aPad
->
GetPosition
().
x
,
aPad
->
GetPosition
().
y
);
m_pads
[
aPad
]
=
nodePtr
;
m_pads
[
aPad
]
=
m_links
.
AddNode
(
aPad
->
GetPosition
().
x
,
aPad
->
GetPosition
().
y
);
m_dirty
=
true
;
}
...
...
@@ -505,7 +521,7 @@ void RN_NET::RemoveItem( const TRACK* aTrack )
{
try
{
RN_EDGE_PTR
&
edge
=
m_tracks
.
at
(
aTrack
);
RN_EDGE_
MST_
PTR
&
edge
=
m_tracks
.
at
(
aTrack
);
// Save nodes, so they can be cleared later
RN_NODE_PTR
aBegin
=
edge
->
GetSourceNode
();
...
...
@@ -546,8 +562,8 @@ void RN_NET::RemoveItem( const ZONE_CONTAINER* aZone )
polygons
.
clear
();
// Remove all connections added by the zone
std
::
deque
<
RN_EDGE_PTR
>&
edges
=
m_zoneConnections
.
at
(
aZone
);
BOOST_FOREACH
(
RN_EDGE_PTR
&
edge
,
edges
)
std
::
deque
<
RN_EDGE_
MST_
PTR
>&
edges
=
m_zoneConnections
.
at
(
aZone
);
BOOST_FOREACH
(
RN_EDGE_PTR
edge
,
edges
)
m_links
.
RemoveConnection
(
edge
);
edges
.
clear
();
...
...
@@ -694,7 +710,7 @@ std::list<RN_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con
case
PCB_TRACE_T
:
{
const
TRACK
*
track
=
static_cast
<
const
TRACK
*>
(
aItem
);
RN_EDGE_PTR
edge
=
m_tracks
.
at
(
track
);
const
RN_EDGE_MST_PTR
&
edge
=
m_tracks
.
at
(
track
);
nodes
.
push_back
(
edge
->
GetSourceNode
()
);
nodes
.
push_back
(
edge
->
GetTargetNode
()
);
...
...
@@ -714,6 +730,76 @@ std::list<RN_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con
}
void
RN_NET
::
ClearSimple
()
{
BOOST_FOREACH
(
const
RN_NODE_PTR
&
node
,
m_simpleNodes
)
node
->
SetFlag
(
false
);
BOOST_FOREACH
(
const
RN_NODE_PTR
&
node
,
m_blockedNodes
)
node
->
SetFlag
(
false
);
m_simpleNodes
.
clear
();
m_blockedNodes
.
clear
();
}
void
RN_NET
::
GetConnectedItems
(
const
BOARD_CONNECTED_ITEM
*
aItem
,
std
::
list
<
BOARD_CONNECTED_ITEM
*>&
aOutput
,
RN_ITEM_TYPES
aTypes
)
const
{
std
::
list
<
RN_NODE_PTR
>
nodes
=
GetNodes
(
aItem
);
assert
(
!
nodes
.
empty
()
);
int
tag
=
nodes
.
front
()
->
GetTag
();
assert
(
tag
>=
0
);
if
(
aTypes
&
RN_PADS
)
{
for
(
PAD_NODE_MAP
::
const_iterator
it
=
m_pads
.
begin
();
it
!=
m_pads
.
end
();
++
it
)
{
if
(
it
->
second
->
GetTag
()
==
tag
)
aOutput
.
push_back
(
const_cast
<
D_PAD
*>
(
it
->
first
)
);
}
}
if
(
aTypes
&
RN_VIAS
)
{
for
(
VIA_NODE_MAP
::
const_iterator
it
=
m_vias
.
begin
();
it
!=
m_vias
.
end
();
++
it
)
{
if
(
it
->
second
->
GetTag
()
==
tag
)
aOutput
.
push_back
(
const_cast
<
VIA
*>
(
it
->
first
)
);
}
}
if
(
aTypes
&
RN_TRACKS
)
{
for
(
TRACK_EDGE_MAP
::
const_iterator
it
=
m_tracks
.
begin
();
it
!=
m_tracks
.
end
();
++
it
)
{
if
(
it
->
second
->
GetTag
()
==
tag
)
aOutput
.
push_back
(
const_cast
<
TRACK
*>
(
it
->
first
)
);
}
}
if
(
aTypes
&
RN_ZONES
)
{
for
(
ZONE_EDGE_MAP
::
const_iterator
it
=
m_zoneConnections
.
begin
();
it
!=
m_zoneConnections
.
end
();
++
it
)
{
const
std
::
deque
<
RN_EDGE_MST_PTR
>&
edges
=
it
->
second
;
BOOST_FOREACH
(
const
RN_EDGE_MST_PTR
&
edge
,
edges
)
{
if
(
edge
->
GetTag
()
==
tag
)
{
aOutput
.
push_back
(
const_cast
<
ZONE_CONTAINER
*>
(
it
->
first
)
);
break
;
}
}
}
}
}
void
RN_DATA
::
AddSimple
(
const
BOARD_ITEM
*
aItem
)
{
int
net
;
...
...
@@ -784,11 +870,46 @@ void RN_DATA::AddSimple( const VECTOR2I& aPosition, int aNetCode )
}
void
RN_DATA
::
GetConnectedItems
(
const
BOARD_CONNECTED_ITEM
*
aItem
,
std
::
list
<
BOARD_CONNECTED_ITEM
*>&
aOutput
,
RN_ITEM_TYPES
aTypes
)
const
{
int
net
=
aItem
->
GetNetCode
();
if
(
net
<
1
)
return
;
assert
(
net
<
(
int
)
m_nets
.
size
()
);
m_nets
[
net
].
GetConnectedItems
(
aItem
,
aOutput
,
aTypes
);
}
bool
RN_DATA
::
AreConnected
(
const
BOARD_CONNECTED_ITEM
*
aItem
,
const
BOARD_CONNECTED_ITEM
*
aOther
)
{
int
net1
=
aItem
->
GetNetCode
();
int
net2
=
aOther
->
GetNetCode
();
if
(
net1
<
1
||
net2
<
1
||
net1
!=
net2
)
return
false
;
assert
(
net1
<
(
int
)
m_nets
.
size
()
&&
net2
<
(
int
)
m_nets
.
size
()
);
// net1 == net2
std
::
list
<
RN_NODE_PTR
>
items1
=
m_nets
[
net1
].
GetNodes
(
aItem
);
std
::
list
<
RN_NODE_PTR
>
items2
=
m_nets
[
net1
].
GetNodes
(
aOther
);
assert
(
!
items1
.
empty
()
&&
!
items2
.
empty
()
);
return
(
items1
.
front
()
->
GetTag
()
==
items2
.
front
()
->
GetTag
()
);
}
void
RN_NET
::
processZones
()
{
BOOST_FOREACH
(
std
::
deque
<
RN_EDGE_PTR
>&
edges
,
m_zoneConnections
|
boost
::
adaptors
::
map_values
)
BOOST_FOREACH
(
std
::
deque
<
RN_EDGE_
MST_
PTR
>&
edges
,
m_zoneConnections
|
boost
::
adaptors
::
map_values
)
{
BOOST_FOREACH
(
RN_EDGE_
PTR
&
edge
,
edges
)
BOOST_FOREACH
(
RN_EDGE_
MST_PTR
edge
,
edges
)
m_links
.
RemoveConnection
(
edge
);
edges
.
clear
();
...
...
@@ -814,7 +935,7 @@ void RN_NET::processZones()
{
if
(
poly
->
HitTest
(
*
point
)
)
{
const
RN_EDGE_PTR
&
connection
=
m_links
.
AddConnection
(
poly
->
GetNode
(),
*
point
);
RN_EDGE_MST_PTR
connection
=
m_links
.
AddConnection
(
poly
->
GetNode
(),
*
point
);
m_zoneConnections
[
poly
->
GetParent
()].
push_back
(
connection
);
// This point already belongs to a polygon, we do not need to check it anymore
...
...
pcbnew/ratsnest_data.h
View file @
190af5d9
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* Copyright (C) 2013
-2015
CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
...
...
@@ -49,6 +49,16 @@ class TRACK;
class
ZONE_CONTAINER
;
class
CPolyPt
;
///> Types of items that are handled by the class
enum
RN_ITEM_TYPES
{
RN_PADS
=
0x01
,
RN_VIAS
=
0x02
,
RN_TRACKS
=
0x04
,
RN_ZONES
=
0x08
,
RN_ALL
=
0xFF
};
// Preserve KiCad coding style policy
typedef
hed
::
NODE
RN_NODE
;
typedef
hed
::
NODE_PTR
RN_NODE_PTR
;
...
...
@@ -157,8 +167,8 @@ public:
* @param aDistance is the distance of the connection (0 means that nodes are actually
* connected, >0 means a missing connection).
*/
const
RN_EDGE_PTR
&
AddConnection
(
const
RN_NODE_PTR
&
aNode1
,
const
RN_NODE_PTR
&
aNode2
,
unsigned
int
aDistance
=
0
);
RN_EDGE_MST_PTR
AddConnection
(
const
RN_NODE_PTR
&
aNode1
,
const
RN_NODE_PTR
&
aNode2
,
unsigned
int
aDistance
=
0
);
/**
* Function RemoveConnection()
...
...
@@ -181,7 +191,7 @@ public:
}
protected
:
///> Set of nodes that are
used are expected to be connected together
.
///> Set of nodes that are
expected to be connected together (vias, tracks, pads)
.
RN_NODE_SET
m_nodes
;
///> List of edges that currently connect nodes.
...
...
@@ -210,7 +220,6 @@ public:
return
m_node
;
}
/**
* Function GetParent()
* Returns pointer to zone that is the owner of subpolygon.
...
...
@@ -307,7 +316,7 @@ public:
* Returns pointer to a vector of edges that makes ratsnest for a given net.
* @return Pointer to a vector of edges that makes ratsnest for a given net.
*/
const
std
::
vector
<
RN_EDGE_PTR
>*
GetUnconnected
()
const
const
std
::
vector
<
RN_EDGE_
MST_
PTR
>*
GetUnconnected
()
const
{
return
m_rnEdges
.
get
();
}
...
...
@@ -429,22 +438,12 @@ public:
std
::
list
<
RN_NODE_PTR
>
GetClosestNodes
(
const
RN_NODE_PTR
&
aNode
,
const
RN_NODE_FILTER
&
aFilter
,
int
aNumber
=
-
1
)
const
;
/**
* Function GetEdges()
* Returns pointer to the vector of edges that makes ratsnest for a given net.
* @return Pointer to the vector of edges that makes ratsnest for a given net.
*/
const
std
::
vector
<
RN_EDGE_PTR
>*
GetEdges
()
const
{
return
m_rnEdges
.
get
();
}
/**
* Function AddSimpleNode()
* Changes drawing mode for a node to simple (i.e. one ratsnest line per node).
* @param aNode is a node that changes its drawing mode.
*/
void
AddSimpleNode
(
RN_NODE_PTR
&
aNode
)
inline
void
AddSimpleNode
(
RN_NODE_PTR
&
aNode
)
{
m_simpleNodes
.
push_back
(
aNode
);
aNode
->
SetFlag
(
true
);
...
...
@@ -456,7 +455,7 @@ public:
* target the node). The status is cleared after calling ClearSimple().
* @param aNode is the node that is not going to be used as a ratsnest line target.
*/
void
AddBlockedNode
(
RN_NODE_PTR
&
aNode
)
inline
void
AddBlockedNode
(
RN_NODE_PTR
&
aNode
)
{
m_blockedNodes
.
push_back
(
aNode
);
aNode
->
SetFlag
(
true
);
...
...
@@ -468,7 +467,7 @@ public:
* ratsnest line per node).
* @return list of nodes for which ratsnest is drawn in simple mode.
*/
const
std
::
deque
<
RN_NODE_PTR
>&
GetSimpleNodes
()
const
inline
const
std
::
deque
<
RN_NODE_PTR
>&
GetSimpleNodes
()
const
{
return
m_simpleNodes
;
}
...
...
@@ -477,22 +476,23 @@ public:
* Function ClearSimple()
* Removes all nodes and edges that are used for displaying ratsnest in simple mode.
*/
void
ClearSimple
()
{
BOOST_FOREACH
(
const
RN_NODE_PTR
&
node
,
m_simpleNodes
)
node
->
SetFlag
(
false
);
BOOST_FOREACH
(
const
RN_NODE_PTR
&
node
,
m_blockedNodes
)
node
->
SetFlag
(
false
);
void
ClearSimple
();
m_simpleNodes
.
clear
();
m_blockedNodes
.
clear
();
}
/**
* Function GetConnectedItems()
* Adds items that are connected together to a list.
* @param aItem is the reference item to find other connected items.
* @param aOutput is the list that will contain found items.
* @param aTypes allows to filter by item types.
*/
void
GetConnectedItems
(
const
BOARD_CONNECTED_ITEM
*
aItem
,
std
::
list
<
BOARD_CONNECTED_ITEM
*>&
aOutput
,
RN_ITEM_TYPES
aTypes
=
RN_ALL
)
const
;
protected
:
///> Validates edge, i.e. modifies source and target nodes for an edge
///> to make sure that they are not ones with the flag set.
void
validateEdge
(
RN_EDGE_PTR
&
aEdge
);
void
validateEdge
(
RN_EDGE_
MST_
PTR
&
aEdge
);
///> Removes all ratsnest edges for a given node.
void
clearNode
(
const
RN_NODE_PTR
&
aNode
);
...
...
@@ -507,31 +507,37 @@ protected:
RN_LINKS
m_links
;
///> Vector of edges that makes ratsnest for a given net.
boost
::
shared_ptr
<
std
::
vector
<
RN_EDGE_PTR
>
>
m_rnEdges
;
boost
::
shared_ptr
<
std
::
vector
<
RN_EDGE_
MST_
PTR
>
>
m_rnEdges
;
///> List of nodes for which ratsnest is drawn in simple mode.
std
::
deque
<
RN_NODE_PTR
>
m_simpleNodes
;
///> List of nodes which
should be used as ratsnest target nodes.
.
///> List of nodes which
will not be used as ratsnest target nodes
.
std
::
deque
<
RN_NODE_PTR
>
m_blockedNodes
;
///> Flag indicating necessity of recalculation of ratsnest for a net.
bool
m_dirty
;
///> Helper typedefs
typedef
boost
::
unordered_map
<
const
D_PAD
*
,
RN_NODE_PTR
>
PAD_NODE_MAP
;
typedef
boost
::
unordered_map
<
const
VIA
*
,
RN_NODE_PTR
>
VIA_NODE_MAP
;
typedef
boost
::
unordered_map
<
const
TRACK
*
,
RN_EDGE_MST_PTR
>
TRACK_EDGE_MAP
;
typedef
boost
::
unordered_map
<
const
ZONE_CONTAINER
*
,
std
::
deque
<
RN_POLY
>
>
ZONE_POLY_MAP
;
typedef
boost
::
unordered_map
<
const
ZONE_CONTAINER
*
,
std
::
deque
<
RN_EDGE_MST_PTR
>
>
ZONE_EDGE_MAP
;
///> Map that associates nodes in the ratsnest model to respective nodes.
boost
::
unordered_map
<
const
D_PAD
*
,
RN_NODE_PTR
>
m_pads
;
PAD_NODE_MAP
m_pads
;
///> Map that associates nodes in the ratsnest model to respective vias.
boost
::
unordered_map
<
const
VIA
*
,
RN_NODE_PTR
>
m_vias
;
VIA_NODE_MAP
m_vias
;
///> Map that associates edges in the ratsnest model to respective tracks.
boost
::
unordered_map
<
const
TRACK
*
,
RN_EDGE_PTR
>
m_tracks
;
TRACK_EDGE_MAP
m_tracks
;
///> Map that associates groups of subpolygons in the ratsnest model to
their
respective zones.
boost
::
unordered_map
<
const
ZONE_CONTAINER
*
,
std
::
deque
<
RN_POLY
>
>
m_zonePolygons
;
///> Map that associates groups of subpolygons in the ratsnest model to respective zones.
ZONE_POLY_MAP
m_zonePolygons
;
///> Map that associates groups of edges in the ratsnest model to
their
respective zones.
boost
::
unordered_map
<
const
ZONE_CONTAINER
*
,
std
::
deque
<
RN_EDGE_PTR
>
>
m_zoneConnections
;
///> Map that associates groups of edges in the ratsnest model to respective zones.
ZONE_EDGE_MAP
m_zoneConnections
;
///> Visibility flag.
bool
m_visible
;
...
...
@@ -646,6 +652,26 @@ public:
return
m_nets
[
aNetCode
];
}
/**
* Function GetConnectedItems()
* Adds items that are connected together to a list.
* @param aItem is the reference item to find other connected items.
* @param aOutput is the list that will contain found items.
* @param aTypes allows to filter by item types.
*/
void
GetConnectedItems
(
const
BOARD_CONNECTED_ITEM
*
aItem
,
std
::
list
<
BOARD_CONNECTED_ITEM
*>&
aOutput
,
RN_ITEM_TYPES
aTypes
=
RN_ALL
)
const
;
/**
* Function AreConnected()
* Checks if two items are connected with copper.
* @param aThis is the first item.
* @param aOther is the second item.
* @return True if they are connected, false otherwise.
*/
bool
AreConnected
(
const
BOARD_CONNECTED_ITEM
*
aItem
,
const
BOARD_CONNECTED_ITEM
*
aOther
);
protected
:
/**
* Function updateNet()
...
...
pcbnew/ratsnest_viewitem.cpp
View file @
190af5d9
...
...
@@ -72,7 +72,7 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
// Set brighter color for the temporary ratsnest
aGal
->
SetStrokeColor
(
color
.
Brightened
(
0.8
)
);
// Draw the "dynamic" ratsnest (ie. for objects that may be currently being moved)
// Draw the "dynamic" ratsnest (i
.
e. for objects that may be currently being moved)
BOOST_FOREACH
(
const
RN_NODE_PTR
&
node
,
net
.
GetSimpleNodes
()
)
{
RN_NODE_PTR
dest
=
net
.
GetClosestNode
(
node
,
WITHOUT_FLAG
()
);
...
...
@@ -93,11 +93,12 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
if
(
i
!=
highlightedNet
)
aGal
->
SetStrokeColor
(
color
);
// using the default ratsnest color for not highlighted
const
std
::
vector
<
RN_EDGE_PTR
>*
edges
=
net
.
GetUnconnected
();
const
std
::
vector
<
RN_EDGE_MST_PTR
>*
edges
=
net
.
GetUnconnected
();
if
(
edges
==
NULL
)
continue
;
BOOST_FOREACH
(
const
RN_EDGE_PTR
&
edge
,
*
edges
)
BOOST_FOREACH
(
const
RN_EDGE_
MST_
PTR
&
edge
,
*
edges
)
{
const
RN_NODE_PTR
&
sourceNode
=
edge
->
GetSourceNode
();
const
RN_NODE_PTR
&
targetNode
=
edge
->
GetTargetNode
();
...
...
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