KiCad PCB EDA Suite
Loading...
Searching...
No Matches
junction_helpers.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "junction_helpers.h"
21
22#include <sch_line.h>
23
24using namespace JUNCTION_HELPERS;
25
27 bool aBreakCrossings )
28{
29 enum layers
30 {
31 WIRES = 0,
32 BUSES
33 };
34
36 info.hasBusEntry = false;
37 info.hasExplicitJunctionDot = false;
38 info.isJunction = false;
39 info.hasBusEntryToMultipleWires = false;
40
41 bool breakLines[2] = { false };
42 std::unordered_set<int> exitAngles[2];
43 std::vector<const SCH_LINE*> midPointLines[2];
44
45 // A pin at 90° still shouldn't match a line at 90° so just give pins unique numbers
46 int uniqueAngle = 10000;
47
48 for( const SCH_ITEM* item : aItems.Overlapping( aPosition ) )
49 {
50 if( item->GetEditFlags() & STRUCT_DELETED )
51 continue;
52
53 switch( item->Type() )
54 {
55 case SCH_JUNCTION_T:
56 if( item->HitTest( aPosition, -1 ) )
57 info.hasExplicitJunctionDot = true;
58
59 break;
60
61 case SCH_LINE_T:
62 {
63 const SCH_LINE* line = static_cast<const SCH_LINE*>( item );
64 int layer;
65
66 if( line->GetStartPoint() == line->GetEndPoint() )
67 break;
68 else if( line->GetLayer() == LAYER_WIRE )
69 layer = WIRES;
70 else if( line->GetLayer() == LAYER_BUS )
71 layer = BUSES;
72 else
73 break;
74
75 if( line->IsConnected( aPosition ) )
76 {
77 breakLines[layer] = true;
78 exitAngles[layer].insert( line->GetAngleFrom( aPosition ) );
79 }
80 else if( line->HitTest( aPosition, -1 ) )
81 {
82 if( aBreakCrossings )
83 breakLines[layer] = true;
84
85 // Defer any line midpoints until we know whether or not we're breaking them
86 midPointLines[layer].push_back( line );
87 }
88 }
89 break;
90
92 if( item->IsConnected( aPosition ) )
93 {
94 breakLines[BUSES] = true;
95 exitAngles[BUSES].insert( uniqueAngle++ );
96 breakLines[WIRES] = true;
97 exitAngles[WIRES].insert( uniqueAngle++ );
98 info.hasBusEntry = true;
99 }
100
101 break;
102
103 case SCH_SYMBOL_T:
104 case SCH_SHEET_T:
105 if( item->IsConnected( aPosition ) )
106 {
107 breakLines[WIRES] = true;
108 exitAngles[WIRES].insert( uniqueAngle++ );
109 }
110
111 break;
112
113 default: break;
114 }
115 }
116
117 for( int layer : { WIRES, BUSES } )
118 {
119 if( breakLines[layer] )
120 {
121 for( const SCH_LINE* line : midPointLines[layer] )
122 {
123 exitAngles[layer].insert( line->GetAngleFrom( aPosition ) );
124 exitAngles[layer].insert( line->GetReverseAngleFrom( aPosition ) );
125 }
126 }
127 }
128
129 if( info.hasBusEntry )
130 {
131 // The bus entry and one wire is 2 wires, and the one entry is exactly one bus
132 // Any more wires must be multiple wires, but any more buses means a wire
133 // crossing at the bus entry root.
134 info.hasBusEntryToMultipleWires =
135 exitAngles[WIRES].size() > 2 && exitAngles[BUSES].size() == 1;
136 }
137
138 // Any three things of the same type is a junction of some sort
139 info.isJunction = exitAngles[WIRES].size() >= 3 || exitAngles[BUSES].size() >= 3;
140
141 return info;
142}
Implements an R-tree for fast spatial and type indexing of schematic items.
Definition: sch_rtree.h:40
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition: sch_rtree.h:243
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:167
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:282
bool IsConnected(const VECTOR2I &aPoint) const
Test the item to see if it is connected to aPoint.
Definition: sch_item.cpp:209
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:41
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_line.cpp:798
int GetAngleFrom(const VECTOR2I &aPoint) const
Definition: sch_line.cpp:411
VECTOR2I GetEndPoint() const
Definition: sch_line.h:141
VECTOR2I GetStartPoint() const
Definition: sch_line.h:136
#define STRUCT_DELETED
flag indication structures to be erased
@ LAYER_WIRE
Definition: layer_ids.h:440
@ LAYER_BUS
Definition: layer_ids.h:441
POINT_INFO AnalyzePoint(const EE_RTREE &aItem, const VECTOR2I &aPosition, bool aBreakCrossings)
Check a tree of items for a confluence at a given point and work out what kind of junction it is,...
A selection of information about a point in the schematic that might be eligible for turning into a j...
@ SCH_LINE_T
Definition: typeinfo.h:163
@ SCH_SYMBOL_T
Definition: typeinfo.h:172
@ SCH_SHEET_T
Definition: typeinfo.h:174
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:161
@ SCH_JUNCTION_T
Definition: typeinfo.h:159