KiCad PCB EDA Suite
Loading...
Searching...
No Matches
bus-wire-junction.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 (C) 2004 Jean-Pierre Charras, [email protected]
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <core/kicad_algo.h>
26#include <general.h>
27#include <sch_bus_entry.h>
28#include <sch_edit_frame.h>
29#include <sch_junction.h>
30#include <sch_line.h>
31#include <sch_no_connect.h>
32#include <sch_commit.h>
33#include <tool/tool_manager.h>
36#include <trigo.h>
37
38
40{
41 std::function<void( SCH_ITEM* )> changeHandler =
42 [&]( SCH_ITEM* aChangedItem ) -> void
43 {
44 GetCanvas()->GetView()->Update( aChangedItem, KIGFX::REPAINT );
45 };
46
47 GetScreen()->TestDanglingEnds( nullptr, &changeHandler );
48}
49
50
51bool SCH_EDIT_FRAME::TrimWire( SCH_COMMIT* aCommit, const VECTOR2I& aStart, const VECTOR2I& aEnd )
52{
53 if( aStart == aEnd )
54 return false;
55
56 SCH_SCREEN* screen = GetScreen();
57 std::vector<SCH_LINE*> wires;
58 BOX2I bb( aStart );
59
61 bb.Merge( aEnd );
62
63 // We cannot modify the RTree while iterating, so push the possible
64 // wires into a separate structure.
65 for( EDA_ITEM* item : screen->Items().Overlapping( bb ) )
66 {
67 SCH_LINE* line = static_cast<SCH_LINE*>( item );
68
69 if( item->Type() == SCH_LINE_T && line->GetLayer() == LAYER_WIRE )
70 wires.push_back( line );
71 }
72
73 for( SCH_LINE* line : wires )
74 {
75 // Don't remove wires that are already deleted or are currently being dragged
76 if( line->GetEditFlags() & ( STRUCT_DELETED | IS_MOVING | SKIP_STRUCT ) )
77 continue;
78
79 if( !IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), aStart ) ||
80 !IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), aEnd ) )
81 {
82 continue;
83 }
84
85 // Don't remove entire wires
86 if( ( line->GetStartPoint() == aStart && line->GetEndPoint() == aEnd )
87 || ( line->GetStartPoint() == aEnd && line->GetEndPoint() == aStart ) )
88 {
89 continue;
90 }
91
92 // Step 1: break the segment on one end.
93 // Ensure that *line points to the segment containing aEnd
94 SCH_LINE* new_line;
95 lwbTool->BreakSegment( aCommit, line, aStart, &new_line, screen );
96
97 if( IsPointOnSegment( new_line->GetStartPoint(), new_line->GetEndPoint(), aEnd ) )
98 line = new_line;
99
100 // Step 2: break the remaining segment.
101 // Ensure that *line _also_ contains aStart. This is our overlapping segment
102 lwbTool->BreakSegment( aCommit, line, aEnd, &new_line, screen );
103
104 if( IsPointOnSegment( new_line->GetStartPoint(), new_line->GetEndPoint(), aStart ) )
105 line = new_line;
106
107 RemoveFromScreen( line, screen );
108 aCommit->Removed( line, screen );
109
110 return true;
111 }
112
113 return false;
114}
115
116
118{
119 SCH_SCREEN* screen = GetScreen();
120 PICKED_ITEMS_LIST undoList;
121 SCH_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<SCH_SELECTION_TOOL>();
122
123 aJunction->SetFlags( STRUCT_DELETED );
124 RemoveFromScreen( aJunction, screen );
125 aCommit->Removed( aJunction, screen );
126
129 std::list<SCH_LINE*> lines;
130
131 for( SCH_ITEM* item : screen->Items().Overlapping( SCH_LINE_T, aJunction->GetPosition() ) )
132 {
133 SCH_LINE* line = static_cast<SCH_LINE*>( item );
134
135 if( ( line->IsWire() || line->IsBus() )
136 && line->IsEndPoint( aJunction->GetPosition() )
137 && !( line->GetEditFlags() & STRUCT_DELETED ) )
138 {
139 lines.push_back( line );
140 }
141 }
142
143 alg::for_all_pairs( lines.begin(), lines.end(),
144 [&]( SCH_LINE* firstLine, SCH_LINE* secondLine )
145 {
146 if( ( firstLine->GetEditFlags() & STRUCT_DELETED )
147 || ( secondLine->GetEditFlags() & STRUCT_DELETED )
148 || !secondLine->IsParallel( firstLine ) )
149 {
150 return;
151 }
152
153 // Remove identical lines
154 if( firstLine->IsEndPoint( secondLine->GetStartPoint() )
155 && firstLine->IsEndPoint( secondLine->GetEndPoint() ) )
156 {
157 firstLine->SetFlags( STRUCT_DELETED );
158 return;
159 }
160
161 // Try to merge the remaining lines
162 if( SCH_LINE* new_line = secondLine->MergeOverlap( screen, firstLine, false ) )
163 {
164 firstLine->SetFlags( STRUCT_DELETED );
165 secondLine->SetFlags( STRUCT_DELETED );
166 AddToScreen( new_line, screen );
167 aCommit->Added( new_line, screen );
168
169 if( new_line->IsSelected() )
170 selectionTool->AddItemToSel( new_line, true /*quiet mode*/ );
171
172 lines.push_back( new_line );
173 }
174 } );
175
176 for( SCH_LINE* line : lines )
177 {
178 if( line->GetEditFlags() & STRUCT_DELETED )
179 {
180 if( line->IsSelected() )
181 selectionTool->RemoveItemFromSel( line, true /*quiet mode*/ );
182
183 RemoveFromScreen( line, screen );
184 aCommit->Removed( line, screen );
185 }
186 }
187}
188
190{
191 std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> items;
192
193 GetCanvas()->GetView()->Query( aItem->GetBoundingBox(), items );
194
195 for( const auto& it : items )
196 {
197 if( !it.first->IsSCH_ITEM() )
198 continue;
199
200 SCH_ITEM* item = static_cast<SCH_ITEM*>( it.first );
201
202 if( item == aItem )
203 continue;
204
205 if( item->IsType( { SCH_ITEM_LOCATE_WIRE_T } ) )
206 {
207 GetCanvas()->GetView()->Update( item );
208 }
209 }
210}
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:658
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Definition commit.h:96
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:98
virtual VECTOR2I GetPosition() const
Definition eda_item.h:272
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:110
EDA_ITEM_FLAGS GetEditFlags() const
Definition eda_item.h:148
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:142
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition sch_rtree.h:246
void Update(const KIGFX::VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition sch_view.cpp:60
int Query(const BOX2I &aRect, std::vector< LAYER_ITEM_PAIR > &aResult) const
Find all visible items that touch or are within the rectangle aRect.
Definition view.cpp:420
A holder to handle information on schematic or board items.
void RemoveFromScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen) override
Remove an item from the screen (and view) aScreen is the screen the item is located on,...
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
KIGFX::SCH_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
bool TrimWire(SCH_COMMIT *aCommit, const VECTOR2I &aStart, const VECTOR2I &aEnd)
If any single wire passes through both points, remove the portion between the two points,...
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
void DeleteJunction(SCH_COMMIT *aCommit, SCH_ITEM *aItem)
Remove a given junction and heals any wire segments under the junction.
void UpdateHopOveredWires(SCH_ITEM *aItem)
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:309
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition sch_item.h:182
Tool responsible for drawing/placing items (symbols, wires, buses, labels, etc.)
void BreakSegment(SCH_COMMIT *aCommit, SCH_LINE *aSegment, const VECTOR2I &aPoint, SCH_LINE **aNewSegment, SCH_SCREEN *aScreen)
Break a single segment into two at the specified point.
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:42
bool IsWire() const
Return true if the line is a wire.
Definition sch_line.cpp:961
VECTOR2I GetEndPoint() const
Definition sch_line.h:144
VECTOR2I GetStartPoint() const
Definition sch_line.h:139
SCH_LINE * MergeOverlap(SCH_SCREEN *aScreen, SCH_LINE *aLine, bool aCheckJunctions)
Check line against aLine to see if it overlaps and merge if it does.
Definition sch_line.cpp:429
bool IsBus() const
Return true if the line is a bus.
Definition sch_line.cpp:967
bool IsEndPoint(const VECTOR2I &aPoint) const override
Test if aPt is an end point of this schematic object.
Definition sch_line.h:91
void TestDanglingEnds(const SCH_SHEET_PATH *aPath=nullptr, std::function< void(SCH_ITEM *)> *aChangedHandler=nullptr) const
Test all of the connectable objects in the schematic for unused connection points.
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:117
TOOL_MANAGER * m_toolManager
#define STRUCT_DELETED
flag indication structures to be erased
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define IS_MOVING
Item being moved.
@ LAYER_WIRE
Definition layer_ids.h:451
@ REPAINT
Item needs to be redrawn.
Definition view_item.h:58
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
Definition kicad_algo.h:84
bool IsPointOnSegment(const VECTOR2I &aSegStart, const VECTOR2I &aSegEnd, const VECTOR2I &aTestPoint)
Test if aTestPoint is on line defined by aSegStart and aSegEnd.
Definition trigo.cpp:89
@ SCH_LINE_T
Definition typeinfo.h:165
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695