KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_drag_net_collision.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 * Copyright (C) 2025 VUT Brno, Faculty of Electrical Engineering and Communication
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 3
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/gpl-3.0.html
20 * or you may search the http://www.gnu.org website for the version 3 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
26
27#include <trace_helpers.h>
28
29#include <algorithm>
30#include <limits>
31#include <unordered_set>
32
33#include <eda_item.h>
34#include <sch_connection.h>
35#include <sch_edit_frame.h>
36#include <sch_item.h>
37#include <sch_junction.h>
38#include <sch_screen.h>
39#include <sch_selection.h>
40#include <sch_sheet_path.h>
41#include <view/view.h>
42#include <view/view_overlay.h>
43#include <gal/color4d.h>
44#include <layer_ids.h>
46#include <eeschema_settings.h>
47
59
60
65
66
68{
69 wxLogTrace( traceSchDragNetCollision, "Initialize: Starting initialization" );
70
71 m_itemNetCodes.clear();
73 m_sheetPath = m_frame->GetCurrentSheet();
74 m_hasCollision = false;
75
76 EE_RTREE& items = m_frame->GetScreen()->Items();
77
78 wxLogTrace( traceSchDragNetCollision, "Initialize: Recording nets for %zu screen items",
79 items.size() );
80
81 for( SCH_ITEM* item : items )
82 recordItemNet( item );
83
84 wxLogTrace( traceSchDragNetCollision, "Initialize: Recording nets for %d selected items",
85 aSelection.GetSize() );
86
87 for( EDA_ITEM* edaItem : aSelection )
88 recordItemNet( static_cast<SCH_ITEM*>( edaItem ) );
89
90 recordOriginalConnections( aSelection );
91
92 wxLogTrace( traceSchDragNetCollision, "Initialize: Complete. Tracked %zu items with net codes",
93 m_itemNetCodes.size() );
94}
95
96
97bool SCH_DRAG_NET_COLLISION_MONITOR::Update( const std::vector<SCH_JUNCTION*>& aJunctions,
98 const SCH_SELECTION& aSelection,
99 std::span<const PREVIEW_NET_ASSIGNMENT> aPreviewAssignments )
100{
101 wxLogTrace( traceSchDragNetCollision, "Update: Called with %zu junctions, %d selected items, %zu preview assignments",
102 aJunctions.size(), aSelection.GetSize(), aPreviewAssignments.size() );
103
104 std::unordered_map<const SCH_ITEM*, std::optional<int>> previewNetCodes;
105
106 previewNetCodes.reserve( aPreviewAssignments.size() );
107
108 for( const PREVIEW_NET_ASSIGNMENT& assignment : aPreviewAssignments )
109 {
110 if( !assignment.item )
111 continue;
112
113 wxLogTrace( traceSchDragNetCollision, "Update: Preview assignment - item %p, netCode %s",
114 assignment.item,
115 assignment.netCode.has_value() ? std::to_string( *assignment.netCode ).c_str() : "none" );
116
117 previewNetCodes[ assignment.item ] = assignment.netCode;
118 }
119
120 std::vector<COLLISION_MARKER> markers;
121
122 if( aJunctions.empty() )
123 {
124 wxLogTrace( traceSchDragNetCollision, "Update: No junctions to analyze" );
125 }
126 else
127 {
128 wxLogTrace( traceSchDragNetCollision, "Update: Analyzing %zu junctions", aJunctions.size() );
129
130 for( SCH_JUNCTION* junction : aJunctions )
131 {
132 if( auto marker = analyzeJunction( junction, aSelection, previewNetCodes ) )
133 {
134 wxLogTrace( traceSchDragNetCollision, "Update: Junction at (%d, %d) has collision",
135 marker->position.x, marker->position.y );
136 markers.push_back( *marker );
137 }
138 }
139 }
140
141 std::vector<DISCONNECTION_MARKER> disconnections = collectDisconnectedMarkers( aSelection );
142
143 if( markers.empty() && disconnections.empty() )
144 {
145 wxLogTrace( traceSchDragNetCollision, "Update: No collisions or disconnections detected" );
146 clearOverlay();
147 m_hasCollision = false;
148 return false;
149 }
150
151 wxLogTrace( traceSchDragNetCollision, "Update: Drawing %zu collision markers and %zu disconnection markers",
152 markers.size(), disconnections.size() );
153
155 m_overlay->Clear();
156
157 COLOR4D baseColor( 1.0, 0.0, 0.0, 0.8 );
158
159 if( COLOR_SETTINGS* colorSettings = m_frame->GetColorSettings() )
160 {
161 COLOR4D themeColor = colorSettings->GetColor( LAYER_DRAG_NET_COLLISION );
162
163 if( themeColor != COLOR4D::UNSPECIFIED )
164 baseColor = themeColor;
165 }
166
167 double baseAlpha = baseColor.a;
168
169 if( baseAlpha <= 0.0 )
170 baseAlpha = 1.0;
171
172 double fillAlpha = std::clamp( baseAlpha * 0.35, 0.05, 1.0 );
173 double strokeAlpha = std::clamp( baseAlpha, 0.05, 1.0 );
174
175 m_overlay->SetIsFill( true );
176 m_overlay->SetFillColor( baseColor.WithAlpha( fillAlpha ) );
177 m_overlay->SetIsStroke( true );
178 m_overlay->SetStrokeColor( baseColor.WithAlpha( strokeAlpha ) );
179
180 int lineWidthPixels = 4;
181
182 if( EESCHEMA_SETTINGS* cfg = m_frame->eeconfig() )
183 lineWidthPixels = std::max( cfg->m_Selection.drag_net_collision_width, 1 );
184
185 double lineWidth = m_view->ToWorld( lineWidthPixels );
186
187 if( lineWidth <= 0.0 )
188 lineWidth = 1.0;
189
190 m_overlay->SetLineWidth( lineWidth );
191
192 for( const COLLISION_MARKER& marker : markers )
193 m_overlay->Circle( marker.position, marker.radius );
194
195 for( const DISCONNECTION_MARKER& marker : disconnections )
196 {
197 m_overlay->Circle( marker.pointA, marker.radius );
198 m_overlay->Circle( marker.pointB, marker.radius );
199 m_overlay->Line( VECTOR2D( marker.pointA ), VECTOR2D( marker.pointB ) );
200 }
201
202 m_view->Update( m_overlay.get() );
203 m_hasCollision = true;
204 return true;
205}
206
207
209{
210 clearOverlay();
211 m_itemNetCodes.clear();
212 m_originalConnections.clear();
213 m_hasCollision = false;
214}
215
216
218{
219 if( m_hasCollision )
220 return KICURSOR::WARNING;
221
222 return aBaseCursor;
223}
224
225
226std::optional<int> SCH_DRAG_NET_COLLISION_MONITOR::GetNetCode( const SCH_ITEM* aItem ) const
227{
228 if( !aItem )
229 return std::nullopt;
230
231 auto it = m_itemNetCodes.find( aItem );
232
233 if( it != m_itemNetCodes.end() )
234 return it->second;
235
236 if( SCH_CONNECTION* connection = aItem->Connection( &m_sheetPath ) )
237 {
238 if( connection->IsNet() && !connection->IsUnconnected() )
239 {
240 int netCode = connection->NetCode();
241
242 if( netCode > 0 )
243 return netCode;
244 }
245 }
246
247 return std::nullopt;
248}
249
250
251std::optional<SCH_DRAG_NET_COLLISION_MONITOR::COLLISION_MARKER> SCH_DRAG_NET_COLLISION_MONITOR::analyzeJunction(
252 SCH_JUNCTION* aJunction, const SCH_SELECTION& aSelection,
253 const std::unordered_map<const SCH_ITEM*, std::optional<int>>& aPreviewNetCodes ) const
254{
255 if( !aJunction )
256 return std::nullopt;
257
258 VECTOR2I position = aJunction->GetPosition();
259 EE_RTREE& items = m_frame->GetScreen()->Items();
260
261 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: Checking junction at (%d, %d)",
262 position.x, position.y );
263
264 std::unordered_set<int> allNetCodes;
265 std::unordered_set<int> movedNetCodes;
266 std::unordered_set<int> originalNetCodes;
267 std::unordered_set<int> movedOriginalNetCodes;
268 std::unordered_set<int> stationaryOriginalNetCodes;
269
270 auto accumulateNet = [&]( SCH_ITEM* item )
271 {
272 if( !item )
273 {
274 wxLogTrace( traceSchDragNetCollision, " accumulateNet: null item" );
275 return;
276 }
277
278 if( !item->IsConnectable() )
279 {
280 wxLogTrace( traceSchDragNetCollision, " accumulateNet: item %p (%s) not connectable",
281 item, item->GetClass().c_str() );
282 return;
283 }
284
285 if( !item->IsConnected( position ) && !( item->IsType( { SCH_LINE_T } ) && item->HitTest( position ) ) )
286 {
287 wxLogTrace( traceSchDragNetCollision, " accumulateNet: item %p (%s) not connected at (%d, %d)",
288 item, item->GetClass().c_str(), position.x, position.y );
289 return;
290 }
291
292 auto previewIt = aPreviewNetCodes.find( item );
293 auto originalIt = m_itemNetCodes.find( item );
294 std::optional<int> netCodeOpt;
295 std::optional<int> originalNetOpt;
296
297 if( originalIt != m_itemNetCodes.end() )
298 originalNetOpt = originalIt->second;
299
300 if( previewIt != aPreviewNetCodes.end() )
301 {
302 netCodeOpt = previewIt->second;
303 wxLogTrace( traceSchDragNetCollision, " accumulateNet: item %p (%s) using preview net %s",
304 item, item->GetClass().c_str(),
305 netCodeOpt.has_value() ? std::to_string( *netCodeOpt ).c_str() : "none" );
306 }
307 else if( originalIt != m_itemNetCodes.end() )
308 {
309 netCodeOpt = originalIt->second;
310 wxLogTrace( traceSchDragNetCollision, " accumulateNet: item %p (%s) using cached net %s",
311 item, item->GetClass().c_str(),
312 netCodeOpt.has_value() ? std::to_string( *netCodeOpt ).c_str() : "none" );
313 }
314 else
315 {
316 wxLogTrace( traceSchDragNetCollision, " accumulateNet: item %p (%s) has no net code",
317 item, item->GetClass().c_str() );
318 }
319
320 bool isSelectionItem = item->IsSelected() || aSelection.Contains( item );
321 bool isMoved = ( previewIt != aPreviewNetCodes.end() ) || isSelectionItem;
322
323 if( !netCodeOpt )
324 {
325 if( originalNetOpt )
326 {
327 originalNetCodes.insert( *originalNetOpt );
328
329 if( isSelectionItem )
330 movedOriginalNetCodes.insert( *originalNetOpt );
331 else
332 stationaryOriginalNetCodes.insert( *originalNetOpt );
333 }
334
335 wxLogTrace( traceSchDragNetCollision, " accumulateNet: item %p (%s) netCode is nullopt",
336 item, item->GetClass().c_str() );
337 return;
338 }
339
340 int netCode = *netCodeOpt;
341 allNetCodes.insert( netCode );
342
343 wxLogTrace( traceSchDragNetCollision, " accumulateNet: item %p (%s) net %d, moved=%s",
344 item, item->GetClass().c_str(), netCode, isMoved ? "yes" : "no" );
345
346 if( isMoved )
347 movedNetCodes.insert( netCode );
348
349 if( originalNetOpt )
350 {
351 originalNetCodes.insert( *originalNetOpt );
352
353 if( isSelectionItem )
354 movedOriginalNetCodes.insert( *originalNetOpt );
355 else
356 stationaryOriginalNetCodes.insert( *originalNetOpt );
357 }
358 };
359
360 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: Checking items overlapping position" );
361
362 int candidateCount = 0;
363
364 for( SCH_ITEM* candidate : items.Overlapping( position ) )
365 {
366 candidateCount++;
367 accumulateNet( candidate );
368 }
369
370 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: Checked %d overlapping items", candidateCount );
371 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: Checking %d selected items", aSelection.GetSize() );
372
373 for( EDA_ITEM* selected : aSelection )
374 accumulateNet( static_cast<SCH_ITEM*>( selected ) );
375
376 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: Found %zu unique nets, %zu moved nets",
377 allNetCodes.size(), movedNetCodes.size() );
378
379 if( !movedNetCodes.empty() )
380 {
381 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: Moved nets:" );
382
383 for( int netCode : movedNetCodes )
384 wxLogTrace( traceSchDragNetCollision, " - Net %d", netCode );
385 }
386
387 wxLogTrace( traceSchDragNetCollision,
388 "analyzeJunction: Original nets=%zu, moved originals=%zu, stationary originals=%zu",
389 originalNetCodes.size(), movedOriginalNetCodes.size(), stationaryOriginalNetCodes.size() );
390
391 if( !movedOriginalNetCodes.empty() )
392 {
393 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: Moved original nets:" );
394
395 for( int netCode : movedOriginalNetCodes )
396 wxLogTrace( traceSchDragNetCollision, " - Net %d", netCode );
397 }
398
399 if( !stationaryOriginalNetCodes.empty() )
400 {
401 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: Stationary original nets:" );
402
403 for( int netCode : stationaryOriginalNetCodes )
404 wxLogTrace( traceSchDragNetCollision, " - Net %d", netCode );
405 }
406
407 if( allNetCodes.size() >= 2 )
408 {
409 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: All nets at junction:" );
410
411 for( int netCode : allNetCodes )
412 wxLogTrace( traceSchDragNetCollision, " - Net %d", netCode );
413 }
414
415 bool previewCollision = !movedNetCodes.empty() && allNetCodes.size() >= 2;
416
417 bool originalCollision = false;
418
419 if( !movedOriginalNetCodes.empty() && !stationaryOriginalNetCodes.empty() )
420 {
421 for( int movedNet : movedOriginalNetCodes )
422 {
423 for( int stationaryNet : stationaryOriginalNetCodes )
424 {
425 if( movedNet != stationaryNet )
426 {
427 originalCollision = true;
428 break;
429 }
430 }
431
432 if( originalCollision )
433 break;
434 }
435 }
436
437 if( !previewCollision && !originalCollision )
438 {
439 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: No collision (movedNets=%zu, allNets=%zu)",
440 movedNetCodes.size(), allNetCodes.size() );
441 return std::nullopt;
442 }
443
444 if( originalCollision && !previewCollision )
445 {
446 wxLogTrace( traceSchDragNetCollision,
447 "analyzeJunction: Original net mismatch detected under moved endpoints" );
448 }
449
450 COLLISION_MARKER marker;
451 marker.position = position;
452 double base = static_cast<double>( aJunction->GetEffectiveDiameter() );
453 marker.radius = std::max( base * 1.5, 800.0 );
454
455 wxLogTrace( traceSchDragNetCollision, "analyzeJunction: COLLISION DETECTED at (%d, %d) with radius %.1f",
456 position.x, position.y, marker.radius );
457
458 return marker;
459}
460
461
463{
464 if( !aItem )
465 return;
466
467 if( !aItem->IsConnectable() )
468 return;
469
470 if( m_itemNetCodes.find( aItem ) != m_itemNetCodes.end() )
471 return;
472
473 if( SCH_CONNECTION* connection = aItem->Connection( &m_sheetPath ) )
474 {
475 if( connection->IsNet() && !connection->IsUnconnected() )
476 {
477 int netCode = connection->NetCode();
478
479 if( netCode > 0 )
480 {
481 wxLogTrace( traceSchDragNetCollision, "recordItemNet: Item %p (%s) at (%d, %d) -> net %d (%s)",
482 aItem, aItem->GetClass().c_str(),
483 aItem->GetPosition().x, aItem->GetPosition().y,
484 netCode, connection->Name().c_str() );
485 m_itemNetCodes.emplace( aItem, netCode );
486 }
487 else
488 {
489 wxLogTrace( traceSchDragNetCollision, "recordItemNet: Item %p (%s) has invalid netCode %d",
490 aItem, aItem->GetClass().c_str(), netCode );
491 m_itemNetCodes.emplace( aItem, std::nullopt );
492 }
493 }
494 else
495 {
496 wxLogTrace( traceSchDragNetCollision, "recordItemNet: Item %p (%s) connection not a net or unconnected",
497 aItem, aItem->GetClass().c_str() );
498 m_itemNetCodes.emplace( aItem, std::nullopt );
499 }
500 }
501 else
502 {
503 wxLogTrace( traceSchDragNetCollision, "recordItemNet: Item %p (%s) has no connection",
504 aItem, aItem->GetClass().c_str() );
505 m_itemNetCodes.emplace( aItem, std::nullopt );
506 }
507}
508
509
511{
512 wxLogTrace( traceSchDragNetCollision, "recordOriginalConnections: Recording connections for %d items",
513 aSelection.GetSize() );
514
515 // Don't record original connections for new or pasted items (duplicates, pastes)
516 // as they weren't previously connected to anything
517 bool hasNewOrPastedItems = false;
518
519 for( EDA_ITEM* edaItem : aSelection )
520 {
521 if( edaItem->IsNew() || ( edaItem->GetFlags() & IS_PASTED ) )
522 {
523 hasNewOrPastedItems = true;
524 break;
525 }
526 }
527
528 if( hasNewOrPastedItems )
529 {
530 wxLogTrace( traceSchDragNetCollision,
531 "recordOriginalConnections: Skipping - selection contains new or pasted items" );
532 return;
533 }
534
535 EE_RTREE& items = m_frame->GetScreen()->Items();
536
537 for( EDA_ITEM* edaItem : aSelection )
538 {
539 SCH_ITEM* item = static_cast<SCH_ITEM*>( edaItem );
540
541 if( !item || !item->IsConnectable() )
542 continue;
543
544 std::vector<VECTOR2I> points = item->GetConnectionPoints();
545
546 for( size_t index = 0; index < points.size(); ++index )
547 {
548 const VECTOR2I& point = points[index];
549
550 for( SCH_ITEM* candidate : items.Overlapping( point ) )
551 {
552 if( candidate == item || !candidate->IsConnectable() )
553 continue;
554
555 if( !candidate->CanConnect( item ) )
556 continue;
557
558 if( !candidate->IsConnected( point )
559 && !( candidate->IsType( { SCH_LINE_T } ) && candidate->HitTest( point ) ) )
560 {
561 continue;
562 }
563
564 std::vector<VECTOR2I> candidatePoints = candidate->GetConnectionPoints();
565 size_t candidateIndex = std::numeric_limits<size_t>::max();
566
567 for( size_t candidatePos = 0; candidatePos < candidatePoints.size(); ++candidatePos )
568 {
569 if( candidatePoints[candidatePos] == point )
570 {
571 candidateIndex = candidatePos;
572 break;
573 }
574 }
575
576 if( candidateIndex == std::numeric_limits<size_t>::max() )
577 continue;
578
579 SCH_ITEM* firstItem = item;
580 size_t firstIndex = index;
581 SCH_ITEM* secondItem = candidate;
582 size_t secondIndex = candidateIndex;
583
584 if( secondItem < firstItem || ( secondItem == firstItem && secondIndex < firstIndex ) )
585 {
586 std::swap( firstItem, secondItem );
587 std::swap( firstIndex, secondIndex );
588 }
589
590 if( firstItem == secondItem )
591 continue;
592
593 bool firstSelected = firstItem->IsSelected() || aSelection.Contains( firstItem );
594 bool secondSelected = secondItem->IsSelected() || aSelection.Contains( secondItem );
595
596 if( !firstSelected && !secondSelected )
597 continue;
598
599 auto existing = std::find_if( m_originalConnections.begin(), m_originalConnections.end(),
600 [&]( const ORIGINAL_CONNECTION& connection )
601 {
602 return connection.itemA == firstItem && connection.indexA == firstIndex
603 && connection.itemB == secondItem && connection.indexB == secondIndex;
604 } );
605
606 if( existing != m_originalConnections.end() )
607 continue;
608
609 m_originalConnections.push_back( { firstItem, firstIndex, secondItem, secondIndex } );
610 }
611 }
612 }
613
614 wxLogTrace( traceSchDragNetCollision, "recordOriginalConnections: Tracked %zu connections",
615 m_originalConnections.size() );
616}
617
618
619std::vector<SCH_DRAG_NET_COLLISION_MONITOR::DISCONNECTION_MARKER>
621{
622 std::vector<DISCONNECTION_MARKER> markers;
623
624 for( const ORIGINAL_CONNECTION& connection : m_originalConnections )
625 {
626 SCH_ITEM* itemA = connection.itemA;
627 SCH_ITEM* itemB = connection.itemB;
628
629 if( !itemA || !itemB )
630 continue;
631
632 if( !itemA->IsConnectable() || !itemB->IsConnectable() )
633 continue;
634
635 std::vector<VECTOR2I> pointsA = itemA->GetConnectionPoints();
636 std::vector<VECTOR2I> pointsB = itemB->GetConnectionPoints();
637
638 if( connection.indexA >= pointsA.size() || connection.indexB >= pointsB.size() )
639 continue;
640
641 VECTOR2I pointA = pointsA[ connection.indexA ];
642 VECTOR2I pointB = pointsB[ connection.indexB ];
643
644 if( pointA == pointB )
645 continue;
646
647 bool relevant = itemA->IsSelected() || aSelection.Contains( itemA )
648 || itemB->IsSelected() || aSelection.Contains( itemB );
649
650 if( !relevant )
651 continue;
652
653 double radius = std::max( { 800.0,
654 static_cast<double>( itemA->GetPenWidth() ),
655 static_cast<double>( itemB->GetPenWidth() ) } );
656
658 marker.pointA = pointA;
659 marker.pointB = pointB;
660 marker.radius = radius;
661 markers.push_back( marker );
662 }
663
664 if( !markers.empty() )
665 {
666 wxLogTrace( traceSchDragNetCollision,
667 "collectDisconnectedMarkers: Identified %zu disconnections", markers.size() );
668 }
669
670 return markers;
671}
672
673
675{
676 if( !m_overlay )
677 m_overlay = m_view->MakeOverlay();
678}
679
680
682{
683 if( m_overlay )
684 {
685 m_overlay->Clear();
686 m_view->Update( m_overlay.get() );
687 }
688}
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
Color settings are a bit different than most of the settings objects in that there can be more than o...
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
bool IsSelected() const
Definition eda_item.h:127
Implement an R-tree for fast spatial and type indexing of schematic items.
Definition sch_rtree.h:40
size_t size() const
Return the number of items in the tree.
Definition sch_rtree.h:174
EE_TYPE Overlapping(const BOX2I &aRect) const
Definition sch_rtree.h:246
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:104
COLOR4D WithAlpha(double aAlpha) const
Return a color with the same color, but the given alpha.
Definition color4d.h:311
double a
Alpha component.
Definition color4d.h:395
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:66
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
std::optional< COLLISION_MARKER > analyzeJunction(SCH_JUNCTION *aJunction, const SCH_SELECTION &aSelection, const std::unordered_map< const SCH_ITEM *, std::optional< int > > &aPreviewNetCodes) const
std::vector< ORIGINAL_CONNECTION > m_originalConnections
std::vector< DISCONNECTION_MARKER > collectDisconnectedMarkers(const SCH_SELECTION &aSelection) const
std::unordered_map< const SCH_ITEM *, std::optional< int > > m_itemNetCodes
void recordOriginalConnections(const SCH_SELECTION &aSelection)
KICURSOR AdjustCursor(KICURSOR aBaseCursor) const
std::shared_ptr< KIGFX::VIEW_OVERLAY > m_overlay
SCH_DRAG_NET_COLLISION_MONITOR(SCH_EDIT_FRAME *aFrame, KIGFX::VIEW *aView)
std::optional< int > GetNetCode(const SCH_ITEM *aItem) const
bool Update(const std::vector< SCH_JUNCTION * > &aJunctions, const SCH_SELECTION &aSelection, std::span< const PREVIEW_NET_ASSIGNMENT > aPreviewAssignments={})
void Initialize(const SCH_SELECTION &aSelection)
Schematic editor (Eeschema) main window.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:167
virtual bool IsConnectable() const
Definition sch_item.h:507
virtual int GetPenWidth() const
Definition sch_item.h:334
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition sch_item.cpp:352
wxString GetClass() const override
Return the class name.
Definition sch_item.h:177
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition sch_item.h:522
int GetEffectiveDiameter() const
VECTOR2I GetPosition() const override
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition selection.h:105
bool Contains(EDA_ITEM *aItem) const
Definition selection.cpp:84
KICURSOR
Definition cursors.h:44
@ WARNING
Definition cursors.h:50
#define IS_PASTED
Modifier on IS_NEW which indicates it came from clipboard.
const wxChar *const traceSchDragNetCollision
Flag to enable debug output of schematic drag net collision detection.
@ LAYER_DRAG_NET_COLLISION
Definition layer_ids.h:494
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
int radius
wxLogTrace helper definitions.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
VECTOR2< double > VECTOR2D
Definition vector2d.h:694