KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pns_dragger.cpp
Go to the documentation of this file.
1/*
2 * KiRouter - a push-and-(sometimes-)shove PCB router
3 *
4 * Copyright (C) 2013-2014 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * Author: Tomasz Wlostowski <[email protected]>
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "pns_arc.h"
23
24#include "pns_dragger.h"
25#include "pns_shove.h"
26#include "pns_router.h"
27#include "pns_debug_decorator.h"
28#include "pns_walkaround.h"
29
30namespace PNS {
31
33 DRAG_ALGO( aRouter ),
34 m_initialVia( {} ),
35 m_draggedVia( {} )
36{
37 m_world = nullptr;
38 m_lastNode = nullptr;
39 m_mode = DM_SEGMENT;
40 m_draggedSegmentIndex = 0;
41 m_dragStatus = false;
42 m_currentMode = RM_MarkObstacles;
43 m_freeAngleMode = false;
44 m_forceMarkObstaclesMode = false;
45}
46
47
49{
50}
51
52
53bool DRAGGER::propagateViaForces( NODE* node, std::set<VIA*>& vias )
54{
55 VIA* via = *vias.begin();
56
57 VECTOR2I force;
59
60 const int iterLimit = Settings().ViaForcePropIterationLimit();
61
62 if( via->PushoutForce( node, lead, force, ITEM::ANY_T, iterLimit ) )
63 {
64 via->SetPos( via->Pos() + force );
65 return true;
66 }
67
68 return false;
69}
70
71
73{
74 int w2 = aSeg->Width() / 2;
75
76 auto distA = ( aP - aSeg->Seg().A ).EuclideanNorm();
77 auto distB = ( aP - aSeg->Seg().B ).EuclideanNorm();
78
79 VECTOR2I psnap;
80
81 if( distA <= w2 )
82 {
83 psnap = aSeg->Seg().A;
84 }
85 else if( distB <= w2 )
86 {
87 psnap = aSeg->Seg().B;
88 }
89 else
90 {
91 return nullptr;
92 }
93
94 const JOINT *jt = m_world->FindJoint( psnap, aSeg );
95
96 if ( !jt )
97 return nullptr;
98
99 for( ITEM* item : jt->LinkList() )
100 {
101 if( item->IsVirtual() && item->OfKind( ITEM::VIA_T ))
102 return static_cast<VVIA*>( item );
103 }
104
105 return nullptr;
106}
107
108
110{
111 int w2 = aSeg->Width() / 2;
112
115
116 auto distA = ( aP - aSeg->Seg().A ).EuclideanNorm();
117 auto distB = ( aP - aSeg->Seg().B ).EuclideanNorm();
118
119 if( distA < w2 || distB < w2 )
120 {
122
123 if( distB <= distA )
125 }
126 else if( m_freeAngleMode )
127 {
128 if( distB < distA &&
130 ( !m_draggedLine.CLine().IsPtOnArc( static_cast<size_t>(m_draggedSegmentIndex) + 1 ) ) )
131 {
133 }
134
136 }
137 else
138 {
140 }
141
142 return true;
143}
144
145
146bool DRAGGER::startDragArc( const VECTOR2D& aP, ARC* aArc )
147{
149 m_mode = DM_ARC;
150
151 return true;
152}
153
154
156{
157 m_initialVia = aVia->MakeHandle();
159
160 m_mode = DM_VIA;
161
162 return true;
163}
164
166{
167 ITEM_SET rv;
168
169 const JOINT* jt = aNode->FindJoint( handle.pos, handle.layers.Start(), handle.net );
170
171 if( !jt )
172 return rv;
173
174 bool foundVia = false;
175
176 for( ITEM* item : jt->LinkList() )
177 {
178 if( item->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) )
179 {
180 int segIndex;
181 LINKED_ITEM* seg = ( LINKED_ITEM*) item;
182 LINE l = aNode->AssembleLine( seg, &segIndex );
183
184 if( segIndex != 0 )
185 l.Reverse();
186
187 rv.Add( l );
188 }
189 else if( item->OfKind( ITEM::VIA_T ) )
190 {
191 if( !foundVia )
192 {
193 rv.Add( item );
194 foundVia = true;
195 }
196 }
197 }
198
199 return rv;
200}
201
202bool DRAGGER::Start( const VECTOR2I& aP, ITEM_SET& aPrimitives )
203{
204 if( aPrimitives.Empty() )
205 return false;
206
207 ITEM* startItem = aPrimitives[0];
208
209 m_lastNode = nullptr;
214 m_lastValidPoint = aP;
215
218
220
222 {
223 m_shove = std::make_unique<SHOVE>( m_preDragNode, Router() );
224 m_shove->SetLogger( Logger() );
225 m_shove->SetDebugDecorator( Dbg() );
226 m_shove->SetDefaultShovePolicy( SHOVE::SHP_SHOVE );
227 }
228
229 startItem->Unmark( MK_LOCKED );
230
231 PNS_DBG( Dbg(), Message, wxString::Format( "StartDragging: item %p [kind %d]",
232 startItem, (int) startItem->Kind() ) );
233
234 switch( startItem->Kind() )
235 {
236 case ITEM::SEGMENT_T:
237 {
238 SEGMENT* seg = static_cast<SEGMENT*>( startItem );
239 VVIA* vvia = checkVirtualVia( aP, seg );
240
241 if( vvia )
242 return startDragVia( vvia );
243 else
244 return startDragSegment( aP, seg );
245 }
246 case ITEM::VIA_T:
247 return startDragVia( static_cast<VIA*>( startItem ) );
248
249 case ITEM::ARC_T:
250 return startDragArc( aP, static_cast<ARC*>( startItem ) );
251
252 default:
253 return false;
254 }
255}
256
257
259{
260 m_mode = static_cast<int>( aMode );
261}
262
263
265{
266 return static_cast<PNS::DRAG_MODE>( m_mode );
267}
268
269
270const std::vector<NET_HANDLE> DRAGGER::CurrentNets() const
271{
272 if( m_mode == PNS::DM_VIA )
273 return std::vector<NET_HANDLE>( 1, m_draggedVia.net );
274 else
275 return std::vector<NET_HANDLE>( 1, m_draggedLine.Net() );
276}
277
278
280{
281 // fixme: rewrite using shared_ptr...
282 if( m_lastNode )
283 {
284 delete m_lastNode;
285 m_lastNode = nullptr;
286 }
287
289
290 switch( m_mode )
291 {
292 case DM_SEGMENT:
293 case DM_CORNER:
294 {
295 //TODO: Make threshold configurable
296 int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
297 LINE origLine( m_draggedLine );
298 LINE dragged( m_draggedLine );
299 dragged.SetSnapThreshhold( thresh );
300 dragged.ClearLinks();
301
302 if( m_mode == DM_SEGMENT )
303 dragged.DragSegment( aP, m_draggedSegmentIndex );
304 else
306
307 m_lastNode->Remove( origLine );
308 m_lastNode->Add( dragged );
309
311 m_draggedItems.Add( dragged );
312
313 break;
314 }
315
316 case DM_VIA: // fixme...
318
319 break;
320 }
321
322 if( Settings().AllowDRCViolations() )
323 m_dragStatus = true;
324 else
326
327 return true;
328}
329
330
331bool DRAGGER::dragViaMarkObstacles( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP )
332{
334
335 ITEM_SET fanout = findViaFanoutByHandle( aNode, aHandle );
336
337 if( fanout.Empty() )
338 return true;
339
340 for( ITEM* item : fanout.Items() )
341 {
342 if( const LINE* l = dyn_cast<const LINE*>( item ) )
343 {
344 LINE origLine( *l );
345 LINE draggedLine( *l );
346
347 draggedLine.DragCorner( aP, origLine.CLine().Find( aHandle.pos ), m_freeAngleMode );
348 draggedLine.ClearLinks();
349
350 m_draggedItems.Add( draggedLine );
351
352 m_lastNode->Remove( origLine );
353 m_lastNode->Add( draggedLine );
354 }
355 else if ( VIA *via = dyn_cast<VIA*>( item ) )
356 {
357 auto nvia = Clone( *via );
358
359 nvia->SetPos( aP );
360 m_draggedItems.Add( nvia.get() );
361
363 m_lastNode->Add( std::move( nvia ) );
364 }
365 }
366
367 return true;
368}
369
370
371bool DRAGGER::dragViaWalkaround( const VIA_HANDLE& aHandle, NODE* aNode, const VECTOR2I& aP )
372{
374
375 ITEM_SET fanout = findViaFanoutByHandle( aNode, aHandle );
376
377 if( fanout.Empty() )
378 return true;
379
380 bool viaPropOk = false;
381 VECTOR2I viaTargetPos;
382
383 for( ITEM* item : fanout.Items() )
384 {
385 if( VIA *via = dyn_cast<VIA*>( item ) )
386 {
387 std::unique_ptr<VIA> draggedVia = Clone( *via );
388
389 draggedVia->SetPos( aP );
390 m_draggedItems.Add( draggedVia.get() );
391
392 std::set<VIA*> vias;
393
394 vias.insert( draggedVia.get() );
395
397
398 bool ok = propagateViaForces( m_lastNode, vias );
399
400 if( ok )
401 {
402 viaTargetPos = draggedVia->Pos();
403 viaPropOk = true;
404 m_lastNode->Add( std::move(draggedVia) );
405 }
406 }
407 }
408
409 if( !viaPropOk ) // can't force-propagate the via? bummer...
410 return false;
411
412 for( ITEM* item : fanout.Items() )
413 {
414 if( const LINE* l = dyn_cast<const LINE*>( item ) )
415 {
416 LINE origLine( *l );
417 LINE draggedLine( *l );
418 LINE walkLine( *l );
419
420 draggedLine.DragCorner( viaTargetPos, origLine.CLine().Find( aHandle.pos ),
422 draggedLine.ClearLinks();
423
424 if ( m_world->CheckColliding( &draggedLine ) )
425 {
426 bool ok = tryWalkaround( m_lastNode, draggedLine, walkLine );
427
428 if( !ok )
429 return false;
430
431 m_lastNode->Remove( origLine );
432 optimizeAndUpdateDraggedLine( walkLine, origLine, aP );
433 }
434 else
435 {
436 m_draggedItems.Add( draggedLine );
437
438 m_lastNode->Remove( origLine );
439 m_lastNode->Add( draggedLine );
440 }
441 }
442 }
443
444 return true;
445}
446
447
448void DRAGGER::optimizeAndUpdateDraggedLine( LINE& aDragged, const LINE& aOrig, const VECTOR2I& aP )
449{
450 LINE draggedPostOpt, origLine( aOrig );
451
452 aDragged.ClearLinks();
453 aDragged.Unmark();
454
455 if( Settings().GetOptimizeEntireDraggedTrack() )
456 {
457 OPTIMIZER optimizer( m_lastNode );
458
459 int effort =
461
462 if( Settings().SmoothDraggedSegments() )
464
465 optimizer.SetEffortLevel( effort );
466
467 OPT_BOX2I affectedArea = aDragged.ChangedArea( &aOrig );
468 VECTOR2I anchor( aP );
469
470 if( aDragged.CLine().Find( aP ) < 0 )
471 anchor = aDragged.CLine().NearestPoint( aP );
472
473 optimizer.SetPreserveVertex( anchor );
474
475 if( !affectedArea )
476 affectedArea = BOX2I( aP ); // No valid area yet? set to minimum to disable optimization
477
478 PNS_DBG( Dbg(), AddPoint, anchor, YELLOW, 100000, wxT( "drag-anchor" ) );
479 PNS_DBG( Dbg(), AddShape, *affectedArea, RED, 0, wxT( "drag-affected-area" ) );
480
481 optimizer.SetRestrictArea( *affectedArea );
482
483 PNS_DBG( Dbg(), AddItem, aDragged.Clone(), RED, 0, wxT( "drag-preopt" ) );
484 aDragged.Line().Split( anchor );
485
486 optimizer.Optimize( &aDragged, &draggedPostOpt, &origLine );
487 PNS_DBG( Dbg(), AddItem, aDragged.Clone(), GREEN, 0, wxT( "drag-postopt" ) );
488 }
489 else
490 {
491 draggedPostOpt = aDragged;
492 }
493
494 m_lastNode->Add( draggedPostOpt );
496 m_draggedItems.Add( draggedPostOpt );
497}
498
499
500bool DRAGGER::tryWalkaround( NODE* aNode, LINE& aOrig, LINE& aWalk )
501{
502 WALKAROUND walkaround( aNode, Router() );
503 bool ok = false;
504 walkaround.SetSolidsOnly( false );
505 walkaround.SetDebugDecorator( Dbg() );
506 walkaround.SetLogger( Logger() );
507 walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
508 walkaround.SetLengthLimit( true, 30.0 );
510
511 aWalk = aOrig;
512
513 WALKAROUND::RESULT wr = walkaround.Route( aWalk );
514
516 {
517 aWalk = wr.lines[ WALKAROUND::WP_SHORTEST ];
518 return true;
519 }
520
521 return false;
522}
523
524
526{
527 bool ok = false;
528
529 // fixme: rewrite using shared_ptr...
530 if( m_lastNode )
531 {
532 delete m_lastNode;
533 m_lastNode = nullptr;
534 }
535
537
538 switch( m_mode )
539 {
540 case DM_SEGMENT:
541 case DM_CORNER:
542 {
543 int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
544 LINE dragged( m_draggedLine );
545 LINE draggedWalk( m_draggedLine );
546 LINE origLine( m_draggedLine );
547
548 dragged.SetSnapThreshhold( thresh );
549
550 if( m_mode == DM_SEGMENT )
551 dragged.DragSegment( aP, m_draggedSegmentIndex );
552 else
553 dragged.DragCorner( aP, m_draggedSegmentIndex );
554
555 if ( m_world->CheckColliding( &dragged ) )
556 {
557 ok = tryWalkaround( m_lastNode, dragged, draggedWalk );
558 }
559 else
560 {
561 draggedWalk = dragged;
562 ok = true;
563 }
564
565 if( draggedWalk.CLine().PointCount() < 2 )
566 ok = false;
567
568 if( ok )
569 {
570 PNS_DBG( Dbg(), AddShape, &origLine.CLine(), BLUE, 50000, wxT( "drag-orig-line" ) );
571 PNS_DBG( Dbg(), AddShape, &draggedWalk.CLine(), CYAN, 75000, wxT( "drag-walk" ) );
572 m_lastNode->Remove( origLine );
573 optimizeAndUpdateDraggedLine( draggedWalk, origLine, aP );
574 }
575
576 break;
577 }
578 case DM_VIA: // fixme...
580 break;
581 }
582
583 m_dragStatus = ok;
584
585 return ok;
586}
587
588
590{
591
592 if( m_lastNode )
593 {
594 delete m_lastNode;
595 m_lastNode = nullptr;
596 }
597
598 switch( m_mode )
599 {
600 case DM_SEGMENT:
601 case DM_CORNER:
602 {
603 bool ok = false;
604 //TODO: Make threshold configurable
605 int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 2 : 0;
606 LINE draggedPreShove( m_draggedLine );
607 draggedPreShove.SetSnapThreshhold( thresh );
608
609 if( m_mode == DM_SEGMENT )
610 draggedPreShove.DragSegment( aP, m_draggedSegmentIndex );
611 else
612 draggedPreShove.DragCorner( aP, m_draggedSegmentIndex );
613
614 auto preShoveNode = m_shove->CurrentNode();
615
616 if( preShoveNode )
617 {
618 preShoveNode->Remove( draggedPreShove );
619 }
620
621 m_shove->ClearHeads();
622 m_shove->AddHeads( draggedPreShove, SHOVE::SHP_SHOVE | SHOVE::SHP_DONT_LOCK_ENDPOINTS );
623 ok = m_shove->Run() == SHOVE::SH_OK;
624
625 LINE draggedPostShove( draggedPreShove );
626
627 if( ok )
628 {
629 if( m_shove->HeadsModified() )
630 {
631 draggedPostShove = m_shove->GetModifiedHead( 0 );
632 }
633 }
634
635 m_lastNode = m_shove->CurrentNode()->Branch();
636
637 if( ok )
638 {
639 VECTOR2D lockV;
640 draggedPostShove.ClearLinks();
641 draggedPostShove.Unmark();
642 optimizeAndUpdateDraggedLine( draggedPostShove, m_draggedLine, aP );
643 m_lastDragSolution = draggedPostShove;
644 }
645
646 m_dragStatus = ok;
647 break;
648 }
649
650 case DM_VIA:
651 {
652 VIA_HANDLE newVia;
653
654 // corner count limiter intended to avoid excessive optimization produces mediocre results for via shoving.
655 // this is a hack that disables it, before I figure out a more reliable solution
656 m_shove->DisablePostShoveOptimizations( OPTIMIZER::LIMIT_CORNER_COUNT );
657
658 m_shove->ClearHeads();
659 m_shove->AddHeads( m_draggedVia, aP, SHOVE::SHP_SHOVE );
660
661 SHOVE::SHOVE_STATUS st = m_shove->Run(); //ShoveDraggingVia( m_draggedVia, aP, newVia );
662
663 PNS_DBG( Dbg(), Message, wxString::Format("head-mod %d",
664 m_shove->HeadsModified() ? 1: 0 ) );
665
666 if( m_shove->HeadsModified() )
667 {
668 newVia = m_shove->GetModifiedHeadVia( 0 );
669
670 PNS_DBG( Dbg(), Message, wxString::Format("newvia %d %d %d %d",
671 newVia.pos.x,
672 newVia.pos.y,
673 newVia.layers.Start(),
674 newVia.layers.End()
675 ) );
676
677 m_draggedVia = newVia;
678 }
679
680
681 m_lastNode = m_shove->CurrentNode()->Branch();
682
684
685 // If drag didn't work (i.e. dragged onto a collision) try walkaround instead
686 if( st != SHOVE::SH_OK )
688 else
689 m_dragStatus = true;
690
691 break;
692 }
693 }
694
695 return m_dragStatus;
696}
697
698
699bool DRAGGER::FixRoute( bool aForceCommit )
700{
701 NODE* node = CurrentNode();
702
703 if( node )
704 {
705 if( m_dragStatus )
706 {
707 Router()->CommitRouting( node );
708 return true;
709 }
710 else if( m_forceMarkObstaclesMode )
711 {
712 if( aForceCommit )
713 {
714 Router()->CommitRouting( node );
715 return true;
716 }
717
718 return false;
719 }
720 else
721 {
722 // If collisions exist, we can fix in shove/smart mode because all tracks to be
723 // committed will be in valid positions (even if the current routing solution to
724 // the mouse cursor is invalid).
726 node = CurrentNode();
727
728 if( node && m_dragStatus )
729 {
730 Router()->CommitRouting( node );
731 return true;
732 }
733 }
734 }
735
736 return false;
737}
738
739
740bool DRAGGER::Drag( const VECTOR2I& aP )
741{
743
744 bool ret = false;
745
747 {
748 ret = dragMarkObstacles( aP );
749 }
750 else
751 {
752 switch( m_currentMode )
753 {
754 case RM_MarkObstacles: ret = dragMarkObstacles( aP ); break;
755 case RM_Shove: ret = dragShove( aP ); break;
756 case RM_Walkaround: ret = dragWalkaround( aP ); break;
757 default: break;
758 }
759 }
760
761 if( ret )
762 {
763 m_lastValidPoint = aP;
764 }
765 else
766 {
767 if( m_lastNode )
768 {
769 NODE* parent = m_lastNode->GetParent()->Branch();
770 delete m_lastNode;
771 m_lastNode = parent;
775 }
776 }
777
778 return ret;
779}
780
781
783{
784 return m_lastNode ? m_lastNode : m_world;
785}
786
787
789{
790 return m_draggedItems;
791}
792
793}
BOX2< VECTOR2I > BOX2I
Definition: box2.h:922
std::optional< BOX2I > OPT_BOX2I
Definition: box2.h:926
void SetDebugDecorator(DEBUG_DECORATOR *aDecorator)
Assign a debug decorator allowing this algo to draw extra graphics for visual debugging.
Definition: pns_algo_base.h:73
void SetLogger(LOGGER *aLogger)
Definition: pns_algo_base.h:65
virtual LOGGER * Logger()
ROUTER * Router() const
Return current router settings.
Definition: pns_algo_base.h:54
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:78
ITEM_SET m_draggedItems
If true, moves the connection lines without maintaining 45 degrees corners.
Definition: pns_dragger.h:163
PNS::DRAG_MODE Mode() const override
bool m_dragStatus
Definition: pns_dragger.h:157
void optimizeAndUpdateDraggedLine(LINE &aDragged, const LINE &aOrig, const VECTOR2I &aP)
const ITEM_SET findViaFanoutByHandle(NODE *aNode, const VIA_HANDLE &handle)
bool startDragSegment(const VECTOR2D &aP, SEGMENT *aSeg)
VECTOR2D m_lastValidPoint
Contains the list of items that are currently modified by the dragger.
Definition: pns_dragger.h:160
virtual bool Start(const VECTOR2I &aP, ITEM_SET &aPrimitives) override
Function Start()
NODE * CurrentNode() const override
Function CurrentNode()
DRAGGER(ROUTER *aRouter)
Definition: pns_dragger.cpp:32
bool dragViaMarkObstacles(const VIA_HANDLE &aHandle, NODE *aNode, const VECTOR2I &aP)
bool Drag(const VECTOR2I &aP) override
Function Drag()
bool startDragVia(VIA *aVia)
LINE m_lastDragSolution
Definition: pns_dragger.h:154
int m_draggedSegmentIndex
Definition: pns_dragger.h:156
const std::vector< NET_HANDLE > CurrentNets() const override
Function CurrentNets()
bool dragShove(const VECTOR2I &aP)
void SetMode(PNS::DRAG_MODE aDragMode) override
bool dragMarkObstacles(const VECTOR2I &aP)
bool FixRoute(bool aForceCommit) override
Function FixRoute()
std::unique_ptr< SHOVE > m_shove
Definition: pns_dragger.h:155
NODE * m_lastNode
Definition: pns_dragger.h:150
LINE m_draggedLine
Definition: pns_dragger.h:153
bool dragWalkaround(const VECTOR2I &aP)
VVIA * checkVirtualVia(const VECTOR2D &aP, SEGMENT *aSeg)
Definition: pns_dragger.cpp:72
VIA_HANDLE m_draggedVia
Definition: pns_dragger.h:148
bool dragViaWalkaround(const VIA_HANDLE &aHandle, NODE *aNode, const VECTOR2I &aP)
bool m_freeAngleMode
Definition: pns_dragger.h:166
bool m_forceMarkObstaclesMode
Definition: pns_dragger.h:167
NODE * m_preDragNode
Definition: pns_dragger.h:151
PNS_MODE m_currentMode
Definition: pns_dragger.h:158
const ITEM_SET Traces() override
Function Traces()
bool tryWalkaround(NODE *aNode, LINE &aOrig, LINE &aWalk)
bool startDragArc(const VECTOR2D &aP, ARC *aArc)
MOUSE_TRAIL_TRACER m_mouseTrailTracer
Definition: pns_dragger.h:168
VIA_HANDLE m_initialVia
Definition: pns_dragger.h:147
bool propagateViaForces(NODE *node, std::set< VIA * > &vias)
Definition: pns_dragger.cpp:53
DRAG_ALGO.
Definition: pns_drag_algo.h:44
bool Empty() const
Definition: pns_itemset.h:82
void Add(const LINE &aLine)
Definition: pns_itemset.cpp:33
std::vector< ITEM * > & Items()
Definition: pns_itemset.h:87
Base class for PNS router board items.
Definition: pns_item.h:98
virtual void Unmark(int aMarker=-1) const
Definition: pns_item.h:262
virtual NET_HANDLE Net() const
Definition: pns_item.h:210
PnsKind Kind() const
Return the type (kind) of the item.
Definition: pns_item.h:173
@ SEGMENT_T
Definition: pns_item.h:107
A 2D point on a given set of layers and belonging to a certain net, that links together a number of b...
Definition: pns_joint.h:43
const std::vector< ITEM * > & LinkList() const
Definition: pns_joint.h:303
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:62
OPT_BOX2I ChangedArea(const LINE *aOther) const
Definition: pns_line.cpp:1219
const SHAPE_LINE_CHAIN & CLine() const
Definition: pns_line.h:138
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:137
void DragCorner(const VECTOR2I &aP, int aIndex, bool aFreeAngle=false, DIRECTION_45 aPreferredEndingDirection=DIRECTION_45())
Definition: pns_line.cpp:789
void SetSnapThreshhold(int aThreshhold)
Definition: pns_line.h:232
virtual void Unmark(int aMarker=-1) const override
Definition: pns_line.cpp:137
int PointCount() const
Definition: pns_line.h:141
void DragSegment(const VECTOR2I &aP, int aIndex, bool aFreeAngle=false)
Definition: pns_line.cpp:803
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
Definition: pns_line.cpp:1078
virtual LINE * Clone() const override
Return a deep copy of the item.
Definition: pns_line.cpp:119
int Width() const
Return true if the line is geometrically identical as line aOther.
Definition: pns_line.h:157
void AddTrailPoint(const VECTOR2I &aP)
Keep the router "world" - i.e.
Definition: pns_node.h:232
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
Definition: pns_node.cpp:143
NODE * GetParent() const
Check if this branch contains an updated version of the m_item from the root branch.
Definition: pns_node.h:486
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Check if the item collides with anything else in the world, and if found, returns the obstacle.
Definition: pns_node.cpp:410
const JOINT * FindJoint(const VECTOR2I &aPos, int aLayer, NET_HANDLE aNet) const
Search for a joint at a given position, layer and belonging to given net.
Definition: pns_node.cpp:1268
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Add an item to the current node.
Definition: pns_node.cpp:665
const LINE AssembleLine(LINKED_ITEM *aSeg, int *aOriginSegmentIndex=nullptr, bool aStopAtLockedJoints=false, bool aFollowLockedSegments=false, bool aAllowSegmentSizeMismatch=true)
Follow the joint map to assemble a line connecting two non-trivial joints starting from segment aSeg.
Definition: pns_node.cpp:1047
void Remove(ARC *aArc)
Remove an item from this branch.
Definition: pns_node.cpp:909
Perform various optimizations of the lines being routed, attempting to make the lines shorter and les...
Definition: pns_optimizer.h:95
void SetPreserveVertex(const VECTOR2I &aV)
void SetRestrictArea(const BOX2I &aArea, bool aStrict=true)
void SetEffortLevel(int aEffort)
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I &aV=VECTOR2I(0, 0))
@ LIMIT_CORNER_COUNT
Do not attempt to optimize if the resulting line's corner count is outside the predefined range.
@ MERGE_SEGMENTS
Reduce corner cost iteratively.
Definition: pns_optimizer.h:99
@ MERGE_COLINEAR
Merge co-linear segments.
void CommitRouting()
Definition: pns_router.cpp:921
int ViaForcePropIterationLimit() const
bool SmoothDraggedSegments() const
Enable/disable smoothing segments during dragging.
PNS_MODE Mode() const
Set the routing mode.
const SEG & Seg() const
Definition: pns_segment.h:93
int Width() const override
Definition: pns_segment.h:88
@ SHP_DONT_LOCK_ENDPOINTS
Definition: pns_shove.h:66
const VIA_HANDLE MakeHandle() const
Definition: pns_via.cpp:286
void SetIterationLimit(const int aIterLimit)
void SetLengthLimit(bool aEnable, double aLengthExpansionFactor)
void SetSolidsOnly(bool aSolidsOnly)
STATUS Route(const LINE &aInitialPath, LINE &aWalkPath, bool aOptimize=true)
void SetAllowedPolicies(std::vector< WALK_POLICY > aPolicies)
int Start() const
Definition: pns_layerset.h:86
int End() const
Definition: pns_layerset.h:91
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
bool IsPtOnArc(size_t aPtIndex) const
int Split(const VECTOR2I &aP, bool aExact=false)
Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
int Find(const VECTOR2I &aP, int aThreshold=0) const
Search for point aP.
@ BLUE
Definition: color4d.h:56
@ GREEN
Definition: color4d.h:57
@ CYAN
Definition: color4d.h:58
@ YELLOW
Definition: color4d.h:67
@ RED
Definition: color4d.h:59
Push and Shove diff pair dimensions (gap) settings dialog.
@ RM_MarkObstacles
Ignore collisions, mark obstacles.
@ RM_Walkaround
Only walk around.
@ RM_Shove
Only shove.
DRAG_MODE
Definition: pns_router.h:71
@ DM_CORNER
Definition: pns_router.h:72
@ DM_FREE_ANGLE
Definition: pns_router.h:75
@ DM_VIA
Definition: pns_router.h:74
@ DM_SEGMENT
Definition: pns_router.h:73
@ DM_ARC
Definition: pns_router.h:76
@ MK_LOCKED
Definition: pns_item.h:45
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:344
#define PNS_DBG(dbg, method,...)
VECTOR2I pos
Definition: pns_via.h:53
NET_HANDLE net
Definition: pns_via.h:55
PNS_LAYER_RANGE layers
Definition: pns_via.h:54
LINE lines[MaxWalkPolicies]
STATUS status[MaxWalkPolicies]