forked from KiCad/kicad-source-mirror
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjunction_helpers.cpp
123 lines (101 loc) · 3.57 KB
/
junction_helpers.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "junction_helpers.h"
#include <sch_line.h>
using namespace JUNCTION_HELPERS;
POINT_INFO JUNCTION_HELPERS::AnalyzePoint( const EE_RTREE& aItems, const VECTOR2I& aPosition,
bool aBreakCrossings )
{
enum layers
{
WIRES = 0,
BUSES
};
POINT_INFO info{};
info.hasBusEntry = false;
info.hasExplicitJunctionDot = false;
info.isJunction = false;
info.hasBusEntryToMultipleWires = false;
bool breakLines[2] = { false };
std::unordered_set<int> exitAngles[2];
std::vector<const SCH_LINE*> midPointLines[2];
// A pin at 90° still shouldn't match a line at 90° so just give pins unique numbers
int uniqueAngle = 10000;
for( const SCH_ITEM* item : aItems.Overlapping( aPosition ) )
{
if( item->GetEditFlags() & STRUCT_DELETED )
continue;
switch( item->Type() )
{
case SCH_JUNCTION_T:
if( item->HitTest( aPosition, -1 ) )
info.hasExplicitJunctionDot = true;
break;
case SCH_LINE_T:
{
const SCH_LINE* line = static_cast<const SCH_LINE*>( item );
int layer;
if( line->GetStartPoint() == line->GetEndPoint() )
break;
else if( line->GetLayer() == LAYER_WIRE )
layer = WIRES;
else if( line->GetLayer() == LAYER_BUS )
layer = BUSES;
else
break;
if( line->IsConnected( aPosition ) )
{
breakLines[layer] = true;
exitAngles[layer].insert( line->GetAngleFrom( aPosition ) );
}
else if( line->HitTest( aPosition, -1 ) )
{
if( aBreakCrossings )
breakLines[layer] = true;
// Defer any line midpoints until we know whether or not we're breaking them
midPointLines[layer].push_back( line );
}
}
break;
case SCH_BUS_WIRE_ENTRY_T:
if( item->IsConnected( aPosition ) )
{
breakLines[BUSES] = true;
exitAngles[BUSES].insert( uniqueAngle++ );
breakLines[WIRES] = true;
exitAngles[WIRES].insert( uniqueAngle++ );
info.hasBusEntry = true;
}
break;
case SCH_SYMBOL_T:
case SCH_SHEET_T:
if( item->IsConnected( aPosition ) )
{
breakLines[WIRES] = true;
exitAngles[WIRES].insert( uniqueAngle++ );
}
break;
default: break;
}
}
for( int layer : { WIRES, BUSES } )
{
if( breakLines[layer] )
{
for( const SCH_LINE* line : midPointLines[layer] )
{
exitAngles[layer].insert( line->GetAngleFrom( aPosition ) );
exitAngles[layer].insert( line->GetReverseAngleFrom( aPosition ) );
}
}
}
if( info.hasBusEntry )
{
// The bus entry and one wire is 2 wires, and the one entry is exactly one bus
// Any more wires must be multiple wires, but any more buses means a wire
// crossing at the bus entry root.
info.hasBusEntryToMultipleWires =
exitAngles[WIRES].size() > 2 && exitAngles[BUSES].size() == 1;
}
// Any three things of the same type is a junction of some sort
info.isJunction = exitAngles[WIRES].size() >= 3 || exitAngles[BUSES].size() >= 3;
return info;
}