KiCad PCB EDA Suite
pns_kicad_iface.cpp
Go to the documentation of this file.
1/*
2 * KiRouter - a push-and-(sometimes-)shove PCB router
3 *
4 * Copyright (C) 2013-2016 CERN
5 * Copyright (C) 2016-2022 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 <board.h>
25#include <fp_text.h>
26#include <footprint.h>
27#include <pad.h>
28#include <pcb_track.h>
29#include <zone.h>
30#include <pcb_shape.h>
31#include <pcb_text.h>
32#include <board_commit.h>
33#include <layer_ids.h>
35#include <confirm.h>
36#include <tools/pcb_tool_base.h>
37#include <tool/tool_manager.h>
39
40#include <pcb_painter.h>
41
42#include <geometry/shape.h>
44#include <geometry/shape_arc.h>
46
47#include <drc/drc_rule.h>
48#include <drc/drc_engine.h>
49
51
52#include <wx/log.h>
53
54#include <memory>
55
56#include <advanced_config.h>
57#include <pcbnew_settings.h>
58#include <macros.h>
59
60#include "pns_kicad_iface.h"
61
62#include "pns_arc.h"
64#include "pns_sizes_settings.h"
65#include "pns_item.h"
66#include "pns_solid.h"
67#include "pns_segment.h"
68#include "pns_node.h"
69#include "pns_router.h"
70#include "pns_debug_decorator.h"
71#include "router_preview_item.h"
72
74
75
77{
78 const PNS::ITEM* A;
79 const PNS::ITEM* B;
80 bool Flag;
81
82 bool operator==(const CLEARANCE_CACHE_KEY& other) const
83 {
84 return A == other.A && B == other.B && Flag == other.Flag;
85 }
86};
87
88namespace std
89{
90 template <>
92 {
93 std::size_t operator()( const CLEARANCE_CACHE_KEY& k ) const
94 {
95 return hash<const void*>()( k.A ) ^ hash<const void*>()( k.B ) ^ hash<int>()( k.Flag );
96 }
97 };
98}
99
100
102{
103public:
104 PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER_IFACE* aRouterIface );
106
107 virtual int Clearance( const PNS::ITEM* aA, const PNS::ITEM* aB,
108 bool aUseClearanceEpsilon = true ) override;
109 virtual int HoleClearance( const PNS::ITEM* aA, const PNS::ITEM* aB,
110 bool aUseClearanceEpsilon = true ) override;
111 virtual int HoleToHoleClearance( const PNS::ITEM* aA, const PNS::ITEM* aB,
112 bool aUseClearanceEpsilon = true ) override;
113
114 virtual int DpCoupledNet( int aNet ) override;
115 virtual int DpNetPolarity( int aNet ) override;
116 virtual bool DpNetPair( const PNS::ITEM* aItem, int& aNetP, int& aNetN ) override;
117 virtual bool IsDiffPair( const PNS::ITEM* aA, const PNS::ITEM* aB ) override;
118
119 virtual bool IsInNetTie( const PNS::ITEM* aA ) override;
120 virtual bool IsNetTieExclusion( const PNS::ITEM* aItem, const VECTOR2I& aCollisionPos,
121 const PNS::ITEM* aCollidingItem ) override;
122
123 virtual bool QueryConstraint( PNS::CONSTRAINT_TYPE aType, const PNS::ITEM* aItemA,
124 const PNS::ITEM* aItemB, int aLayer,
125 PNS::CONSTRAINT* aConstraint ) override;
126 virtual wxString NetName( int aNet ) override;
127
128 int ClearanceEpsilon() const { return m_clearanceEpsilon; }
129
130 void ClearCacheForItem( const PNS::ITEM* aItem ) override;
131 void ClearCaches() override;
132
133private:
134 int holeRadius( const PNS::ITEM* aItem ) const;
135
145 int matchDpSuffix( const wxString& aNetName, wxString& aComplementNet );
146
147private:
154
155 std::unordered_map<CLEARANCE_CACHE_KEY, int> m_clearanceCache;
156 std::unordered_map<CLEARANCE_CACHE_KEY, int> m_holeClearanceCache;
157 std::unordered_map<CLEARANCE_CACHE_KEY, int> m_holeToHoleClearanceCache;
158};
159
160
162 PNS::ROUTER_IFACE* aRouterIface ) :
163 m_routerIface( aRouterIface ),
164 m_board( aBoard ),
165 m_dummyTracks{ { aBoard }, { aBoard } },
166 m_dummyArcs{ { aBoard }, { aBoard } },
167 m_dummyVias{ { aBoard }, { aBoard } }
168{
169 if( aBoard )
170 m_clearanceEpsilon = aBoard->GetDesignSettings().GetDRCEpsilon();
171 else
172 m_clearanceEpsilon = 0;
173}
174
175
177{
178}
179
180
182{
183 if( aItem->Kind() == PNS::ITEM::SOLID_T )
184 {
185 const PAD* pad = dynamic_cast<const PAD*>( aItem->Parent() );
186
187 if( pad && pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
188 return pad->GetDrillSize().x / 2;
189 }
190 else if( aItem->Kind() == PNS::ITEM::VIA_T )
191 {
192 const PCB_VIA* via = dynamic_cast<const PCB_VIA*>( aItem->Parent() );
193
194 if( via )
195 return via->GetDrillValue() / 2;
196 }
197
198 return 0;
199}
200
201
203{
204 int net_p, net_n;
205
206 if( !DpNetPair( aA, net_p, net_n ) )
207 return false;
208
209 if( aA->Net() == net_p && aB->Net() == net_n )
210 return true;
211
212 if( aB->Net() == net_p && aA->Net() == net_n )
213 return true;
214
215 return false;
216}
217
218
220{
221 BOARD_ITEM* item = aA->Parent();
222 BOARD_ITEM* parentFootprint = item ? item->GetParentFootprint() : nullptr;
223
224 if( parentFootprint )
225 return static_cast<FOOTPRINT*>( parentFootprint )->IsNetTie();
226
227 return false;
228}
229
230
232 const VECTOR2I& aCollisionPos,
233 const PNS::ITEM* aCollidingItem )
234{
235 std::shared_ptr<DRC_ENGINE> drcEngine = m_board->GetDesignSettings().m_DRCEngine;
236 BOARD_ITEM* collidingItem = aCollidingItem->Parent();
237
238 if( drcEngine && collidingItem )
239 {
240 return drcEngine->IsNetTieExclusion( aItem->Net(), ToLAYER_ID( aItem->Layer() ),
241 aCollisionPos, collidingItem );
242 }
243
244 return false;
245}
246
247
248bool isCopper( const PNS::ITEM* aItem )
249{
250 BOARD_ITEM* parent = aItem->Parent();
251
252 if( parent && parent->Type() == PCB_PAD_T )
253 {
254 PAD* pad = static_cast<PAD*>( parent );
255 return pad->IsOnCopperLayer() && pad->GetAttribute() != PAD_ATTRIB::NPTH;
256 }
257
258 return true;
259}
260
261
262bool isEdge( const PNS::ITEM* aItem )
263{
264 const BOARD_ITEM *parent = aItem->Parent();
265
266 return parent && ( parent->IsOnLayer( Edge_Cuts ) || parent->IsOnLayer( Margin ) );
267}
268
269
271 const PNS::ITEM* aItemA, const PNS::ITEM* aItemB,
272 int aLayer, PNS::CONSTRAINT* aConstraint )
273{
274 std::shared_ptr<DRC_ENGINE> drcEngine = m_board->GetDesignSettings().m_DRCEngine;
275
276 if( !drcEngine )
277 return false;
278
279 DRC_CONSTRAINT_T hostType;
280
281 switch ( aType )
282 {
292 default: return false; // should not happen
293 }
294
295 BOARD_ITEM* parentA = aItemA ? aItemA->Parent() : nullptr;
296 BOARD_ITEM* parentB = aItemB ? aItemB->Parent() : nullptr;
297 DRC_CONSTRAINT hostConstraint;
298
299 // A track being routed may not have a BOARD_ITEM associated yet.
300 if( aItemA && !parentA )
301 {
302 switch( aItemA->Kind() )
303 {
304 case PNS::ITEM::ARC_T: parentA = &m_dummyArcs[0]; break;
305 case PNS::ITEM::VIA_T: parentA = &m_dummyVias[0]; break;
306 case PNS::ITEM::SEGMENT_T: parentA = &m_dummyTracks[0]; break;
307 case PNS::ITEM::LINE_T: parentA = &m_dummyTracks[0]; break;
308 default: break;
309 }
310
311 if( parentA )
312 {
313 parentA->SetLayer( ToLAYER_ID( aLayer ) );
314 static_cast<BOARD_CONNECTED_ITEM*>( parentA )->SetNetCode( aItemA->Net(), true );
315 }
316 }
317
318 if( aItemB && !parentB )
319 {
320 switch( aItemB->Kind() )
321 {
322 case PNS::ITEM::ARC_T: parentB = &m_dummyArcs[1]; break;
323 case PNS::ITEM::VIA_T: parentB = &m_dummyVias[1]; break;
324 case PNS::ITEM::SEGMENT_T: parentB = &m_dummyTracks[1]; break;
325 case PNS::ITEM::LINE_T: parentB = &m_dummyTracks[1]; break;
326 default: break;
327 }
328
329 if( parentB )
330 {
331 parentB->SetLayer( ToLAYER_ID( aLayer ) );
332 static_cast<BOARD_CONNECTED_ITEM*>( parentB )->SetNetCode( aItemB->Net(), true );
333 }
334 }
335
336 if( parentA )
337 hostConstraint = drcEngine->EvalRules( hostType, parentA, parentB, ToLAYER_ID( aLayer ) );
338
339 if( hostConstraint.IsNull() )
340 return false;
341
342 if( hostConstraint.GetSeverity() == RPT_SEVERITY_IGNORE )
343 {
344 aConstraint->m_Value.SetMin( -1 );
345 aConstraint->m_RuleName = hostConstraint.GetName();
346 aConstraint->m_Type = aType;
347 return true;
348 }
349
350 switch ( aType )
351 {
360 aConstraint->m_Value = hostConstraint.GetValue();
361 aConstraint->m_RuleName = hostConstraint.GetName();
362 aConstraint->m_Type = aType;
363 return true;
364
365 default:
366 return false;
367 }
368}
369
370
372{
373 CLEARANCE_CACHE_KEY key = { aItem, nullptr, false };
374 m_clearanceCache.erase( key );
375
376 key.Flag = true;
377 m_clearanceCache.erase( key );
378}
379
380
382{
383 m_clearanceCache.clear();
384 m_holeClearanceCache.clear();
386}
387
388
390 bool aUseClearanceEpsilon )
391{
392 CLEARANCE_CACHE_KEY key = { aA, aB, aUseClearanceEpsilon };
393 auto it = m_clearanceCache.find( key );
394
395 if( it != m_clearanceCache.end() )
396 return it->second;
397
398 PNS::CONSTRAINT constraint;
399 int rv = 0;
400 LAYER_RANGE layers;
401
402 if( !aB )
403 layers = aA->Layers();
404 else if( isEdge( aA ) )
405 layers = aB->Layers();
406 else if( isEdge( aB ) )
407 layers = aA->Layers();
408 else
409 layers = aA->Layers().Intersection( aB->Layers() );
410
411 // Normalize layer range (no -1 magic numbers)
413
414 for( int layer = layers.Start(); layer <= layers.End(); ++layer )
415 {
416 if( isCopper( aA ) && ( !aB || isCopper( aB ) ) )
417 {
418 if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_CLEARANCE, aA, aB, layer, &constraint ) )
419 {
420 if( constraint.m_Value.Min() > rv )
421 rv = constraint.m_Value.Min();
422 }
423 }
424
425 if( isEdge( aA ) || ( aB && isEdge( aB ) ) )
426 {
427 if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_EDGE_CLEARANCE, aA, aB, layer, &constraint ) )
428 {
429 if( constraint.m_Value.Min() > rv )
430 rv = constraint.m_Value.Min();
431 }
432 }
433 }
434
435 if( aUseClearanceEpsilon )
436 rv -= m_clearanceEpsilon;
437
438 m_clearanceCache[ key ] = rv;
439 return rv;
440}
441
442
444 bool aUseClearanceEpsilon )
445{
446 CLEARANCE_CACHE_KEY key = { aA, aB, aUseClearanceEpsilon };
447 auto it = m_holeClearanceCache.find( key );
448
449 if( it != m_holeClearanceCache.end() )
450 return it->second;
451
452 PNS::CONSTRAINT constraint;
453 int rv = 0;
454 int layer;
455
456 if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() )
457 layer = aA->Layer();
458 else
459 layer = aB->Layer();
460
461 if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_HOLE_CLEARANCE, aA, aB, layer, &constraint ) )
462 rv = constraint.m_Value.Min();
463
464 if( aUseClearanceEpsilon )
465 rv -= m_clearanceEpsilon;
466
467 m_holeClearanceCache[ key ] = rv;
468 return rv;
469}
470
471
473 bool aUseClearanceEpsilon )
474{
475 CLEARANCE_CACHE_KEY key = { aA, aB, aUseClearanceEpsilon };
476 auto it = m_holeToHoleClearanceCache.find( key );
477
478 if( it != m_holeToHoleClearanceCache.end() )
479 return it->second;
480
481 PNS::CONSTRAINT constraint;
482 int rv = 0;
483 int layer;
484
485 if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() )
486 layer = aA->Layer();
487 else
488 layer = aB->Layer();
489
490 if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_HOLE_TO_HOLE, aA, aB, layer, &constraint ) )
491 rv = constraint.m_Value.Min();
492
493 if( aUseClearanceEpsilon )
494 rv -= m_clearanceEpsilon;
495
496 m_holeToHoleClearanceCache[ key ] = rv;
497 return rv;
498}
499
500
501bool PNS_KICAD_IFACE_BASE::inheritTrackWidth( PNS::ITEM* aItem, int* aInheritedWidth )
502{
503 VECTOR2I p;
504
505 assert( aItem->Owner() != nullptr );
506
507 auto tryGetTrackWidth =
508 []( PNS::ITEM* aPnsItem ) -> int
509 {
510 switch( aPnsItem->Kind() )
511 {
512 case PNS::ITEM::SEGMENT_T: return static_cast<PNS::SEGMENT*>( aPnsItem )->Width();
513 case PNS::ITEM::ARC_T: return static_cast<PNS::ARC*>( aPnsItem )->Width();
514 default: return -1;
515 }
516 };
517
518 int itemTrackWidth = tryGetTrackWidth( aItem );
519
520 if( itemTrackWidth > 0 )
521 {
522 *aInheritedWidth = itemTrackWidth;
523 return true;
524 }
525
526 switch( aItem->Kind() )
527 {
528 case PNS::ITEM::VIA_T:
529 p = static_cast<PNS::VIA*>( aItem )->Pos();
530 break;
531
533 p = static_cast<PNS::SOLID*>( aItem )->Pos();
534 break;
535
536 default:
537 return false;
538 }
539
540 PNS::JOINT* jt = static_cast<PNS::NODE*>( aItem->Owner() )->FindJoint( p, aItem );
541
542 assert( jt != nullptr );
543
544 int mval = INT_MAX;
545
546 PNS::ITEM_SET linkedSegs = jt->Links();
548
549 for( PNS::ITEM* item : linkedSegs.Items() )
550 {
551 int w = tryGetTrackWidth( item );
552 assert( w > 0 );
553 mval = std::min( w, mval );
554 }
555
556 if( mval == INT_MAX )
557 return false;
558
559 *aInheritedWidth = mval;
560 return true;
561}
562
563
565 int aNet )
566{
568 PNS::CONSTRAINT constraint;
569
570 if( aStartItem && m_startLayer < 0 )
571 m_startLayer = aStartItem->Layer();
572
573 aSizes.SetMinClearance( bds.m_MinClearance );
574 aSizes.SetClearanceSource( _( "board minimum clearance" ) );
575
576 int trackWidth = bds.m_TrackMinWidth;
577 bool found = false;
578 aSizes.SetWidthSource( _( "board minimum track width" ) );
579
580 if( bds.m_UseConnectedTrackWidth && !bds.m_TempOverrideTrackWidth && aStartItem != nullptr )
581 {
582 found = inheritTrackWidth( aStartItem, &trackWidth );
583
584 if( found )
585 aSizes.SetWidthSource( _( "existing track" ) );
586 }
587
588 if( !found && bds.UseNetClassTrack() && aStartItem )
589 {
591 m_startLayer, &constraint ) )
592 {
593 trackWidth = std::max( trackWidth, constraint.m_Value.Opt() );
594 found = true;
595
596 if( trackWidth == constraint.m_Value.Opt() )
597 aSizes.SetWidthSource( constraint.m_RuleName );
598 }
599 }
600
601 if( !found )
602 {
603 trackWidth = std::max( trackWidth, bds.GetCurrentTrackWidth() );
604
605 if( bds.UseNetClassTrack() )
606 aSizes.SetWidthSource( _( "netclass 'Default'" ) );
607 else if( trackWidth == bds.GetCurrentTrackWidth() )
608 aSizes.SetWidthSource( _( "user choice" ) );
609 }
610
611 aSizes.SetTrackWidth( trackWidth );
613
614 int viaDiameter = bds.m_ViasMinSize;
615 int viaDrill = bds.m_MinThroughDrill;
616
617 if( bds.UseNetClassVia() && aStartItem ) // netclass value
618 {
620 nullptr, m_startLayer, &constraint ) )
621 {
622 viaDiameter = std::max( viaDiameter, constraint.m_Value.Opt() );
623 }
624
626 nullptr, m_startLayer, &constraint ) )
627 {
628 viaDrill = std::max( viaDrill, constraint.m_Value.Opt() );
629 }
630 }
631 else
632 {
633 viaDiameter = bds.GetCurrentViaSize();
634 viaDrill = bds.GetCurrentViaDrill();
635 }
636
637 aSizes.SetViaDiameter( viaDiameter );
638 aSizes.SetViaDrill( viaDrill );
639
640 int diffPairWidth = bds.m_TrackMinWidth;
641 int diffPairGap = bds.m_MinClearance;
642 int diffPairViaGap = bds.m_MinClearance;
643
644 aSizes.SetDiffPairWidthSource( _( "board minimum track width" ) );
645 aSizes.SetDiffPairGapSource( _( "board minimum clearance" ) );
646
647 found = false;
648
649 // First try to pick up diff pair width from starting track, if enabled
650 if( bds.m_UseConnectedTrackWidth && aStartItem )
651 found = inheritTrackWidth( aStartItem, &diffPairWidth );
652
653 // Next, pick up gap from netclass, and width also if we didn't get a starting width above
654 if( bds.UseNetClassDiffPair() && aStartItem )
655 {
657 nullptr, m_startLayer, &constraint ) )
658 {
659 diffPairWidth = std::max( diffPairWidth, constraint.m_Value.Opt() );
660
661 if( diffPairWidth == constraint.m_Value.Opt() )
662 aSizes.SetDiffPairWidthSource( constraint.m_RuleName );
663 }
664
666 nullptr, m_startLayer, &constraint ) )
667 {
668 diffPairGap = std::max( diffPairGap, constraint.m_Value.Opt() );
669 diffPairViaGap = std::max( diffPairViaGap, constraint.m_Value.Opt() );
670
671 if( diffPairGap == constraint.m_Value.Opt() )
672 aSizes.SetDiffPairGapSource( constraint.m_RuleName );
673 }
674 }
675 else
676 {
677 diffPairWidth = bds.GetCurrentDiffPairWidth();
678 diffPairGap = bds.GetCurrentDiffPairGap();
679 diffPairViaGap = bds.GetCurrentDiffPairViaGap();
680
681 aSizes.SetDiffPairWidthSource( _( "user choice" ) );
682 aSizes.SetDiffPairGapSource( _( "user choice" ) );
683 }
684
685 aSizes.SetDiffPairWidth( diffPairWidth );
686 aSizes.SetDiffPairGap( diffPairGap );
687 aSizes.SetDiffPairViaGap( diffPairViaGap );
688 aSizes.SetDiffPairViaGapSameAsTraceGap( false );
689
690 int holeToHoleMin = bds.m_HoleToHoleMin;
691 PNS::VIA dummyVia;
692
694 &dummyVia, UNDEFINED_LAYER, &constraint ) )
695 {
696 holeToHoleMin = constraint.m_Value.Min();
697 }
698
699 aSizes.SetHoleToHole( holeToHoleMin );
700
701 return true;
702}
703
704
705int PNS_KICAD_IFACE_BASE::StackupHeight( int aFirstLayer, int aSecondLayer ) const
706{
708 return 0;
709
711
712 return stackup.GetLayerDistance( ToLAYER_ID( aFirstLayer ), ToLAYER_ID( aSecondLayer ) );
713}
714
715
716int PNS_PCBNEW_RULE_RESOLVER::matchDpSuffix( const wxString& aNetName, wxString& aComplementNet )
717{
718 int rv = 0;
719 int count = 0;
720
721 for( auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
722 {
723 int ch = *it;
724
725 if( ( ch >= '0' && ch <= '9' ) || ch == '_' )
726 {
727 continue;
728 }
729 else if( ch == '+' )
730 {
731 aComplementNet = wxT( "-" );
732 rv = 1;
733 }
734 else if( ch == '-' )
735 {
736 aComplementNet = wxT( "+" );
737 rv = -1;
738 }
739 else if( ch == 'N' )
740 {
741 aComplementNet = wxT( "P" );
742 rv = -1;
743 }
744 else if ( ch == 'P' )
745 {
746 aComplementNet = wxT( "N" );
747 rv = 1;
748 }
749 else
750 {
751 break;
752 }
753 }
754
755 if( rv != 0 && count >= 1 )
756 {
757 aComplementNet = aNetName.Left( aNetName.length() - count ) + aComplementNet
758 + aNetName.Right( count - 1 );
759 }
760
761 return rv;
762}
763
764
766{
767 wxString refName = m_board->FindNet( aNet )->GetNetname();
768 wxString coupledNetName;
769
770 if( matchDpSuffix( refName, coupledNetName ) )
771 {
772 NETINFO_ITEM* net = m_board->FindNet( coupledNetName );
773
774 if( !net )
775 return -1;
776
777 return net->GetNetCode();
778 }
779
780 return -1;
781}
782
783
785{
786 return m_board->FindNet( aNet )->GetNetname();
787}
788
789
791{
792 wxString refName = m_board->FindNet( aNet )->GetNetname();
793 wxString dummy1;
794
795 return matchDpSuffix( refName, dummy1 );
796}
797
798
799bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( const PNS::ITEM* aItem, int& aNetP, int& aNetN )
800{
801 if( !aItem || !aItem->Parent() || !aItem->Parent()->IsConnected() )
802 return false;
803
804 BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem->Parent() );
805 NETINFO_ITEM* netInfo = cItem->GetNet();
806
807 if( !netInfo )
808 return false;
809
810 wxString netNameP = netInfo->GetNetname();
811 wxString netNameN, netNameCoupled;
812
813 int r = matchDpSuffix( netNameP, netNameCoupled );
814
815 if( r == 0 )
816 {
817 return false;
818 }
819 else if( r == 1 )
820 {
821 netNameN = netNameCoupled;
822 }
823 else
824 {
825 netNameN = netNameP;
826 netNameP = netNameCoupled;
827 }
828
829 NETINFO_ITEM* netInfoP = m_board->FindNet( netNameP );
830 NETINFO_ITEM* netInfoN = m_board->FindNet( netNameN );
831
832 if( !netInfoP || !netInfoN )
833 return false;
834
835 aNetP = netInfoP->GetNetCode();
836 aNetN = netInfoN->GetNetCode();
837
838 return true;
839}
840
841
843{
844public:
847 m_view( nullptr ),
848 m_items( nullptr )
849 {
850 SetView( aView );
851 }
852
854 {
856 delete m_items;
857 }
858
859 void SetView( KIGFX::VIEW* aView )
860 {
861 Clear();
862 delete m_items;
863 m_items = nullptr;
864 m_view = aView;
865
866 if( m_view == nullptr )
867 return;
868
871 m_view->Add( m_items );
872 }
873
874 virtual void AddPoint( const VECTOR2I& aP, const KIGFX::COLOR4D& aColor, int aSize,
875 const wxString& aName = wxT( "" ),
876 const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override
877
878 {
879 #if 0
881
882 l.Append( aP - VECTOR2I( -aSize, -aSize ) );
883 l.Append( aP + VECTOR2I( -aSize, -aSize ) );
884
885 AddLine( l, aColor, 10000, aName );
886
887 l.Clear();
888 l.Append( aP - VECTOR2I( aSize, -aSize ) );
889 l.Append( aP + VECTOR2I( aSize, -aSize ) );
890
891 AddLine( l, aColor, 10000, aName );
892 #endif
893 }
894
895 void Clear() override
896 {
897 if( m_view && m_items )
898 {
901 }
902 }
903
904private:
907};
908
909
911{
912 return m_debugDecorator;
913}
914
915
917{
918 m_ruleResolver = nullptr;
919 m_board = nullptr;
920 m_world = nullptr;
921 m_debugDecorator = nullptr;
922 m_startLayer = -1;
923}
924
925
927{
928 m_tool = nullptr;
929 m_view = nullptr;
930 m_previewItems = nullptr;
931 m_commitFlags = 0;
932}
933
934
936{
937}
938
939
941{
942 delete m_ruleResolver;
943 delete m_debugDecorator;
944
945 if( m_previewItems )
946 {
948 delete m_previewItems;
949 }
950}
951
952
953std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( PAD* aPad )
954{
955 LAYER_RANGE layers( 0, MAX_CU_LAYERS - 1 );
956
957 // ignore non-copper pads except for those with holes
958 if( ( aPad->GetLayerSet() & LSET::AllCuMask() ).none() && aPad->GetDrillSize().x == 0 )
959 return nullptr;
960
961 switch( aPad->GetAttribute() )
962 {
963 case PAD_ATTRIB::PTH:
964 case PAD_ATTRIB::NPTH:
965 break;
966
967 case PAD_ATTRIB::CONN:
968 case PAD_ATTRIB::SMD:
969 {
970 LSET lmsk = aPad->GetLayerSet();
971 bool is_copper = false;
972
973 for( int i = 0; i < MAX_CU_LAYERS; i++ )
974 {
975 if( lmsk[i] )
976 {
977 is_copper = true;
978
979 if( aPad->GetAttribute() != PAD_ATTRIB::NPTH )
980 layers = LAYER_RANGE( i );
981
982 break;
983 }
984 }
985
986 if( !is_copper )
987 return nullptr;
988
989 break;
990 }
991
992 default:
993 wxLogTrace( wxT( "PNS" ), wxT( "unsupported pad type 0x%x" ), aPad->GetAttribute() );
994 return nullptr;
995 }
996
997 std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
998
999 if( aPad->GetAttribute() == PAD_ATTRIB::NPTH )
1000 solid->SetRoutable( false );
1001
1002 solid->SetLayers( layers );
1003 solid->SetNet( aPad->GetNetCode() );
1004 solid->SetParent( aPad );
1005 solid->SetPadToDie( aPad->GetPadToDieLength() );
1006 solid->SetOrientation( aPad->GetOrientation() );
1007
1008 if( aPad->IsFreePad() )
1009 solid->SetIsFreePad();
1010
1011 VECTOR2I wx_c = aPad->ShapePos();
1012 VECTOR2I offset = aPad->GetOffset();
1013
1014 VECTOR2I c( wx_c.x, wx_c.y );
1015
1016 RotatePoint( offset, aPad->GetOrientation() );
1017
1018 solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) );
1019 solid->SetOffset( VECTOR2I( offset.x, offset.y ) );
1020
1021 if( aPad->GetDrillSize().x > 0 )
1022 {
1023 SHAPE_SEGMENT* slot = (SHAPE_SEGMENT*) aPad->GetEffectiveHoleShape()->Clone();
1024
1025 if( aPad->GetAttribute() != PAD_ATTRIB::NPTH )
1026 {
1028 slot->SetWidth( slot->GetWidth() );
1029 }
1030
1031 solid->SetHole( slot );
1032 }
1033
1034 // We generate a single SOLID for a pad, so we have to treat it as ALWAYS_FLASHED and then
1035 // perform layer-specific flashing tests internally.
1036 std::shared_ptr<SHAPE> shape = aPad->GetEffectiveShape( UNDEFINED_LAYER,
1038
1039 if( shape->HasIndexableSubshapes() && shape->GetIndexableSubshapeCount() == 1 )
1040 {
1041 std::vector<const SHAPE*> subshapes;
1042 shape->GetIndexableSubshapes( subshapes );
1043
1044 solid->SetShape( subshapes[0]->Clone() );
1045 }
1046 else
1047 {
1048 solid->SetShape( shape->Clone() );
1049 }
1050
1051 return solid;
1052}
1053
1054
1055std::unique_ptr<PNS::SEGMENT> PNS_KICAD_IFACE_BASE::syncTrack( PCB_TRACK* aTrack )
1056{
1057 auto segment = std::make_unique<PNS::SEGMENT>( SEG( aTrack->GetStart(), aTrack->GetEnd() ),
1058 aTrack->GetNetCode() );
1059
1060 segment->SetWidth( aTrack->GetWidth() );
1061 segment->SetLayers( LAYER_RANGE( aTrack->GetLayer() ) );
1062 segment->SetParent( aTrack );
1063
1064 if( aTrack->IsLocked() )
1065 segment->Mark( PNS::MK_LOCKED );
1066
1067 return segment;
1068}
1069
1070
1071std::unique_ptr<PNS::ARC> PNS_KICAD_IFACE_BASE::syncArc( PCB_ARC* aArc )
1072{
1073 auto arc = std::make_unique<PNS::ARC>(
1074 SHAPE_ARC( aArc->GetStart(), aArc->GetMid(), aArc->GetEnd(), aArc->GetWidth() ),
1075 aArc->GetNetCode() );
1076
1077 arc->SetLayers( LAYER_RANGE( aArc->GetLayer() ) );
1078 arc->SetParent( aArc );
1079
1080 if( aArc->IsLocked() )
1081 arc->Mark( PNS::MK_LOCKED );
1082
1083 return arc;
1084}
1085
1086
1087std::unique_ptr<PNS::VIA> PNS_KICAD_IFACE_BASE::syncVia( PCB_VIA* aVia )
1088{
1089 PCB_LAYER_ID top, bottom;
1090 aVia->LayerPair( &top, &bottom );
1091
1092 auto via = std::make_unique<PNS::VIA>( aVia->GetPosition(),
1093 LAYER_RANGE( aVia->TopLayer(), aVia->BottomLayer() ),
1094 aVia->GetWidth(),
1095 aVia->GetDrillValue(),
1096 aVia->GetNetCode(),
1097 aVia->GetViaType() );
1098
1099 via->SetParent( aVia );
1100
1101 if( aVia->IsLocked() )
1102 via->Mark( PNS::MK_LOCKED );
1103
1104 via->SetIsFree( aVia->GetIsFree() );
1105
1107 via->SetHole( SHAPE_CIRCLE( aVia->GetPosition(),
1108 aVia->GetDrillValue() / 2 ) );
1109
1110 return via;
1111}
1112
1113
1114bool PNS_KICAD_IFACE_BASE::syncZone( PNS::NODE* aWorld, ZONE* aZone, SHAPE_POLY_SET* aBoardOutline )
1115{
1116 SHAPE_POLY_SET* poly;
1117
1118 if( !aZone->GetIsRuleArea() && aZone->GetZoneName().IsEmpty() )
1119 return false;
1120
1121 // TODO handle aZone->GetDoNotAllowVias()
1122 // TODO handle rules which disallow tracks & vias
1123 if( !aZone->GetIsRuleArea() || !aZone->GetDoNotAllowTracks() )
1124 return false;
1125
1126 LSET layers = aZone->GetLayerSet();
1127
1128 poly = aZone->Outline();
1129 poly->CacheTriangulation( false );
1130
1131 if( !poly->IsTriangulationUpToDate() )
1132 {
1133 UNITS_PROVIDER unitsProvider( pcbIUScale, GetUnits() );
1134 KIDIALOG dlg( nullptr, wxString::Format( _( "%s is malformed." ),
1135 aZone->GetSelectMenuText( &unitsProvider ) ),
1137 dlg.ShowDetailedText( wxString::Format( _( "This zone cannot be handled by the router.\n"
1138 "Please verify it is not a self-intersecting "
1139 "polygon." ) ) );
1140 dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1141 dlg.ShowModal();
1142
1143 return false;
1144 }
1145
1146 for( int layer = F_Cu; layer <= B_Cu; layer++ )
1147 {
1148 if( !layers[ layer ] )
1149 continue;
1150
1151 for( int outline = 0; outline < poly->OutlineCount(); outline++ )
1152 {
1153 const SHAPE_POLY_SET::TRIANGULATED_POLYGON* tri = poly->TriangulatedPolygon( outline );
1154
1155 for( size_t i = 0; i < tri->GetTriangleCount(); i++)
1156 {
1157 VECTOR2I a, b, c;
1158 tri->GetTriangle( i, a, b, c );
1159 SHAPE_SIMPLE* triShape = new SHAPE_SIMPLE;
1160
1161 triShape->Append( a );
1162 triShape->Append( b );
1163 triShape->Append( c );
1164
1165 std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
1166
1167 solid->SetLayer( layer );
1168 solid->SetNet( -1 );
1169 solid->SetParent( aZone );
1170 solid->SetShape( triShape );
1171 solid->SetIsCompoundShapePrimitive();
1172 solid->SetRoutable( false );
1173
1174 aWorld->Add( std::move( solid ) );
1175 }
1176 }
1177 }
1178
1179 return true;
1180}
1181
1182
1184{
1185 if( !IsCopperLayer( aLayer ) )
1186 return false;
1187
1188 std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
1189
1190 solid->SetLayer( aLayer );
1191 solid->SetNet( -1 );
1192 solid->SetParent( dynamic_cast<BOARD_ITEM*>( aText ) );
1193 solid->SetShape( aText->GetEffectiveTextShape()->Clone() );
1194 solid->SetRoutable( false );
1195
1196 aWorld->Add( std::move( solid ) );
1197
1198 return true;
1199
1200 /* A coarser (but faster) method:
1201 *
1202 SHAPE_POLY_SET outline;
1203 SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
1204
1205 aText->TransformBoundingBoxToPolygon( &outline, 0 );
1206
1207 for( auto iter = outline.CIterate( 0 ); iter; iter++ )
1208 shape->Append( *iter );
1209
1210 solid->SetShape( shape );
1211
1212 solid->SetLayer( aLayer );
1213 solid->SetNet( -1 );
1214 solid->SetParent( nullptr );
1215 solid->SetRoutable( false );
1216 aWorld->Add( std::move( solid ) );
1217 return true;
1218 */
1219}
1220
1221
1223{
1224 if( aItem->GetLayer() == Edge_Cuts
1225 || aItem->GetLayer() == Margin
1226 || IsCopperLayer( aItem->GetLayer() ) )
1227 {
1228 std::vector<SHAPE*> shapes = aItem->MakeEffectiveShapes();
1229
1230 for( SHAPE* shape : shapes )
1231 {
1232 std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
1233
1234 if( aItem->GetLayer() == Edge_Cuts || aItem->GetLayer() == Margin )
1235 solid->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) );
1236 else
1237 solid->SetLayer( aItem->GetLayer() );
1238
1239 if( aItem->GetLayer() == Edge_Cuts )
1240 {
1241 switch( shape->Type() )
1242 {
1243 case SH_SEGMENT: static_cast<SHAPE_SEGMENT*>( shape )->SetWidth( 0 ); break;
1244 case SH_ARC: static_cast<SHAPE_ARC*>( shape )->SetWidth( 0 ); break;
1245 case SH_LINE_CHAIN: static_cast<SHAPE_LINE_CHAIN*>( shape )->SetWidth( 0 ); break;
1246 default: /* remaining shapes don't have width */ break;
1247 }
1248 }
1249
1250 solid->SetNet( -1 );
1251 solid->SetParent( aItem );
1252 solid->SetShape( shape ); // takes ownership
1253
1254 if( shapes.size() > 1 )
1255 solid->SetIsCompoundShapePrimitive();
1256
1257 solid->SetRoutable( false );
1258
1259 aWorld->Add( std::move( solid ) );
1260 }
1261
1262 return true;
1263 }
1264
1265 return false;
1266}
1267
1268
1270{
1271 m_board = aBoard;
1272 wxLogTrace( wxT( "PNS" ), wxT( "m_board = %p" ), m_board );
1273}
1274
1275
1277{
1278 if( !m_view )
1279 return false;
1280
1281 for( int i = aLayer.Start(); i <= aLayer.End(); i++ )
1282 {
1283 if( m_view->IsLayerVisible( i ) )
1284 return true;
1285 }
1286
1287 return false;
1288}
1289
1290
1291bool PNS_KICAD_IFACE_BASE::IsFlashedOnLayer( const PNS::ITEM* aItem, int aLayer ) const
1292{
1294 if( aLayer < 0 )
1295 return true;
1296
1297 if( aItem->Parent() )
1298 {
1299 switch( aItem->Parent()->Type() )
1300 {
1301 case PCB_VIA_T:
1302 {
1303 const PCB_VIA* via = static_cast<const PCB_VIA*>( aItem->Parent() );
1304
1305 return via->FlashLayer( ToLAYER_ID( aLayer ) );
1306 }
1307
1308 case PCB_PAD_T:
1309 {
1310 const PAD* pad = static_cast<const PAD*>( aItem->Parent() );
1311
1312 return pad->FlashLayer( ToLAYER_ID( aLayer ) );
1313 }
1314
1315 default:
1316 break;
1317 }
1318 }
1319
1320 return aItem->Layers().Overlaps( aLayer );
1321}
1322
1323
1325{
1326 // by default, all items are visible (new ones created by the router have parent == NULL
1327 // as they have not been committed yet to the BOARD)
1328 if( !m_view || !aItem->Parent() )
1329 return true;
1330
1331 BOARD_ITEM* item = aItem->Parent();
1332 bool isOnVisibleLayer = true;
1333 RENDER_SETTINGS* settings = m_view->GetPainter()->GetSettings();
1334
1335 if( settings->GetHighContrast() )
1336 isOnVisibleLayer = item->IsOnLayer( settings->GetPrimaryHighContrastLayer() );
1337
1338 if( m_view->IsVisible( item ) && isOnVisibleLayer )
1339 {
1340 for( PCB_LAYER_ID layer : item->GetLayerSet().Seq() )
1341 {
1342 if( item->ViewGetLOD( layer, m_view ) < m_view->GetScale() )
1343 return true;
1344 }
1345 }
1346
1347 // Items hidden in the router are not hidden on the board
1348 if( m_hiddenItems.find( item ) != m_hiddenItems.end() )
1349 return true;
1350
1351 return false;
1352}
1353
1354
1356{
1357 if( !m_board )
1358 {
1359 wxLogTrace( wxT( "PNS" ), wxT( "No board attached, aborting sync." ) );
1360 return;
1361 }
1362
1363 int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
1364
1365 m_world = aWorld;
1366
1367 for( BOARD_ITEM* gitem : m_board->Drawings() )
1368 {
1369 if ( gitem->Type() == PCB_SHAPE_T || gitem->Type() == PCB_TEXTBOX_T )
1370 {
1371 syncGraphicalItem( aWorld, static_cast<PCB_SHAPE*>( gitem ) );
1372 }
1373 else if( gitem->Type() == PCB_TEXT_T )
1374 {
1375 syncTextItem( aWorld, static_cast<PCB_TEXT*>( gitem ), gitem->GetLayer() );
1376 }
1377 }
1378
1379 SHAPE_POLY_SET buffer;
1380 SHAPE_POLY_SET* boardOutline = nullptr;
1381
1382 if( m_board->GetBoardPolygonOutlines( buffer ) )
1383 boardOutline = &buffer;
1384
1385 for( ZONE* zone : m_board->Zones() )
1386 {
1387 syncZone( aWorld, zone, boardOutline );
1388 }
1389
1390 for( FOOTPRINT* footprint : m_board->Footprints() )
1391 {
1392 for( PAD* pad : footprint->Pads() )
1393 {
1394 if( std::unique_ptr<PNS::SOLID> solid = syncPad( pad ) )
1395 aWorld->Add( std::move( solid ) );
1396
1397 worstClearance = std::max( worstClearance, pad->GetLocalClearance() );
1398
1399 if( pad->GetProperty() == PAD_PROP::CASTELLATED )
1400 {
1401 std::unique_ptr<SHAPE> hole;
1402 hole.reset( pad->GetEffectiveHoleShape()->Clone() );
1403 aWorld->AddEdgeExclusion( std::move( hole ) );
1404 }
1405 }
1406
1407 syncTextItem( aWorld, &footprint->Reference(), footprint->Reference().GetLayer() );
1408 syncTextItem( aWorld, &footprint->Value(), footprint->Value().GetLayer() );
1409
1410 for( FP_ZONE* zone : footprint->Zones() )
1411 syncZone( aWorld, zone, boardOutline );
1412
1413 for( BOARD_ITEM* mgitem : footprint->GraphicalItems() )
1414 {
1415 if( mgitem->Type() == PCB_FP_SHAPE_T || mgitem->Type() == PCB_FP_TEXTBOX_T )
1416 {
1417 syncGraphicalItem( aWorld, static_cast<PCB_SHAPE*>( mgitem ) );
1418 }
1419 else if( mgitem->Type() == PCB_FP_TEXT_T )
1420 {
1421 syncTextItem( aWorld, static_cast<FP_TEXT*>( mgitem ), mgitem->GetLayer() );
1422 }
1423 }
1424 }
1425
1426 for( PCB_TRACK* t : m_board->Tracks() )
1427 {
1428 KICAD_T type = t->Type();
1429
1430 if( type == PCB_TRACE_T )
1431 {
1432 if( auto segment = syncTrack( t ) )
1433 aWorld->Add( std::move( segment ) );
1434 }
1435 else if( type == PCB_ARC_T )
1436 {
1437 if( auto arc = syncArc( static_cast<PCB_ARC*>( t ) ) )
1438 aWorld->Add( std::move( arc ) );
1439 }
1440 else if( type == PCB_VIA_T )
1441 {
1442 if( auto via = syncVia( static_cast<PCB_VIA*>( t ) ) )
1443 aWorld->Add( std::move( via ) );
1444 }
1445 }
1446
1447 // NB: if this were ever to become a long-lived object we would need to dirty its
1448 // clearance cache here....
1449 delete m_ruleResolver;
1451
1453 aWorld->SetMaxClearance( worstClearance + m_ruleResolver->ClearanceEpsilon() );
1454}
1455
1456
1458{
1459 for( auto item : m_hiddenItems )
1460 m_view->SetVisible( item, true );
1461
1462 m_hiddenItems.clear();
1463
1464 if( m_previewItems )
1465 {
1468 }
1469
1470 if( m_debugDecorator )
1472}
1473
1474
1476{
1477 m_debugDecorator = aDec;
1478}
1479
1480
1481void PNS_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit )
1482{
1483 if( aItem->IsVirtual() )
1484 return;
1485
1486 ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_view );
1487
1488 // Note: SEGMENT_T is used for placed tracks; LINE_T is used for the routing head
1490 static int tracksOrVias = tracks | PNS::ITEM::VIA_T;
1491
1492 if( aClearance >= 0 )
1493 {
1494 pitem->SetClearance( aClearance );
1495
1496 auto* settings = static_cast<PCBNEW_SETTINGS*>( m_tool->GetManager()->GetSettings() );
1497
1498 switch( settings->m_Display.m_TrackClearance )
1499 {
1502 pitem->ShowClearance( aItem->OfKind( tracksOrVias ) );
1503 break;
1504
1506 pitem->ShowClearance( aItem->OfKind( tracksOrVias ) && !aEdit );
1507 break;
1508
1509 case SHOW_WHILE_ROUTING:
1510 pitem->ShowClearance( aItem->OfKind( tracks ) && !aEdit );
1511 break;
1512
1513 default:
1514 pitem->ShowClearance( false );
1515 break;
1516 }
1517 }
1518
1519 m_previewItems->Add( pitem );
1521}
1522
1523
1524void PNS_KICAD_IFACE::DisplayRatline( const SHAPE_LINE_CHAIN& aRatline, int aNetCode )
1525{
1526 ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aRatline, m_view );
1527
1528 KIGFX::RENDER_SETTINGS* renderSettings = m_view->GetPainter()->GetSettings();
1529 KIGFX::PCB_RENDER_SETTINGS* rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( renderSettings );
1530 bool colorByNet = rs->GetNetColorMode() != NET_COLOR_MODE::OFF;
1531 COLOR4D defaultColor = rs->GetColor( nullptr, LAYER_RATSNEST );
1532 COLOR4D color = defaultColor;
1533
1534 std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
1535 std::set<int> highlightedNets = rs->GetHighlightNetCodes();
1536 std::map<int, KIGFX::COLOR4D>& netColors = rs->GetNetColorMap();
1537 std::map<wxString, KIGFX::COLOR4D>& ncColors = rs->GetNetclassColorMap();
1538 const std::map<int, wxString>& ncMap = connectivity->GetNetclassMap();
1539
1540 if( colorByNet && netColors.count( aNetCode ) )
1541 color = netColors.at( aNetCode );
1542 else if( colorByNet && ncMap.count( aNetCode ) && ncColors.count( ncMap.at( aNetCode ) ) )
1543 color = ncColors.at( ncMap.at( aNetCode ) );
1544 else
1545 color = defaultColor;
1546
1547 if( color == COLOR4D::UNSPECIFIED )
1548 color = defaultColor;
1549
1550 pitem->SetColor( color.Brightened( 0.5 ).WithAlpha( std::min( 1.0, color.a + 0.4 ) ) );
1551
1552 m_previewItems->Add( pitem );
1554}
1555
1556
1558{
1559 BOARD_ITEM* parent = aItem->Parent();
1560
1561 if( parent )
1562 {
1563 if( m_view->IsVisible( parent ) )
1564 m_hiddenItems.insert( parent );
1565
1566 m_view->SetVisible( parent, false );
1567 m_view->Update( parent, KIGFX::APPEARANCE );
1568 }
1569}
1570
1571
1573{
1574}
1575
1576
1578{
1579 BOARD_ITEM* parent = aItem->Parent();
1580
1581 if( aItem->OfKind( PNS::ITEM::SOLID_T ) )
1582 {
1583 PAD* pad = static_cast<PAD*>( parent );
1584 VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
1585
1586 m_fpOffsets[ pad ].p_old = pos;
1587 return;
1588 }
1589
1590 if( parent )
1591 {
1592 m_commit->Remove( parent );
1593 }
1594}
1595
1596
1598{
1599}
1600
1601
1603{
1604 BOARD_ITEM* board_item = aItem->Parent();
1605
1606 m_commit->Modify( board_item );
1607
1608 switch( aItem->Kind() )
1609 {
1610 case PNS::ITEM::ARC_T:
1611 {
1612 PNS::ARC* arc = static_cast<PNS::ARC*>( aItem );
1613 PCB_ARC* arc_board = static_cast<PCB_ARC*>( board_item );
1614 const SHAPE_ARC* arc_shape = static_cast<const SHAPE_ARC*>( arc->Shape() );
1615 arc_board->SetStart( wxPoint( arc_shape->GetP0() ) );
1616 arc_board->SetEnd( wxPoint( arc_shape->GetP1() ) );
1617 arc_board->SetMid( wxPoint( arc_shape->GetArcMid() ) );
1618 arc_board->SetWidth( arc->Width() );
1619 break;
1620 }
1621
1623 {
1624 PNS::SEGMENT* seg = static_cast<PNS::SEGMENT*>( aItem );
1625 PCB_TRACK* track = static_cast<PCB_TRACK*>( board_item );
1626 const SEG& s = seg->Seg();
1627 track->SetStart( wxPoint( s.A.x, s.A.y ) );
1628 track->SetEnd( wxPoint( s.B.x, s.B.y ) );
1629 track->SetWidth( seg->Width() );
1630 break;
1631 }
1632
1633 case PNS::ITEM::VIA_T:
1634 {
1635 PCB_VIA* via_board = static_cast<PCB_VIA*>( board_item );
1636 PNS::VIA* via = static_cast<PNS::VIA*>( aItem );
1637 via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) );
1638 via_board->SetWidth( via->Diameter() );
1639 via_board->SetDrill( via->Drill() );
1640 via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 );
1641 via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
1642 via_board->SetIsFree( via->IsFree() );
1643 via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
1644 ToLAYER_ID( via->Layers().End() ) );
1645 break;
1646 }
1647
1648 case PNS::ITEM::SOLID_T:
1649 {
1650 PAD* pad = static_cast<PAD*>( aItem->Parent() );
1651 VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
1652
1653 m_fpOffsets[ pad ].p_old = pad->GetPosition();
1654 m_fpOffsets[ pad ].p_new = pos;
1655 break;
1656 }
1657
1658 default:
1659 break;
1660 }
1661}
1662
1663
1665{
1666
1667}
1668
1669
1671{
1672 BOARD_CONNECTED_ITEM* newBI = nullptr;
1673
1674 switch( aItem->Kind() )
1675 {
1676 case PNS::ITEM::ARC_T:
1677 {
1678 PNS::ARC* arc = static_cast<PNS::ARC*>( aItem );
1679 PCB_ARC* new_arc = new PCB_ARC( m_board, static_cast<const SHAPE_ARC*>( arc->Shape() ) );
1680 new_arc->SetWidth( arc->Width() );
1681 new_arc->SetLayer( ToLAYER_ID( arc->Layers().Start() ) );
1682 new_arc->SetNetCode( std::max<int>( 0, arc->Net() ) );
1683 newBI = new_arc;
1684 break;
1685 }
1686
1688 {
1689 PNS::SEGMENT* seg = static_cast<PNS::SEGMENT*>( aItem );
1690 PCB_TRACK* track = new PCB_TRACK( m_board );
1691 const SEG& s = seg->Seg();
1692 track->SetStart( wxPoint( s.A.x, s.A.y ) );
1693 track->SetEnd( wxPoint( s.B.x, s.B.y ) );
1694 track->SetWidth( seg->Width() );
1695 track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) );
1696 track->SetNetCode( seg->Net() > 0 ? seg->Net() : 0 );
1697 newBI = track;
1698 break;
1699 }
1700
1701 case PNS::ITEM::VIA_T:
1702 {
1703 PCB_VIA* via_board = new PCB_VIA( m_board );
1704 PNS::VIA* via = static_cast<PNS::VIA*>( aItem );
1705 via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) );
1706 via_board->SetWidth( via->Diameter() );
1707 via_board->SetDrill( via->Drill() );
1708 via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 );
1709 via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
1710 via_board->SetIsFree( via->IsFree() );
1711 via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
1712 ToLAYER_ID( via->Layers().End() ) );
1713 newBI = via_board;
1714 break;
1715 }
1716
1717 case PNS::ITEM::SOLID_T:
1718 {
1719 PAD* pad = static_cast<PAD*>( aItem->Parent() );
1720 VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
1721
1722 m_fpOffsets[ pad ].p_new = pos;
1723 return;
1724 }
1725
1726 default:
1727 break;
1728 }
1729
1730 if( newBI )
1731 {
1732 //newBI->SetLocalRatsnestVisible( m_dispOptions->m_ShowGlobalRatsnest );
1733 aItem->SetParent( newBI );
1734 newBI->ClearFlags();
1735
1736 m_commit->Add( newBI );
1737 }
1738}
1739
1740
1742{
1743 std::set<FOOTPRINT*> processedFootprints;
1744
1745 EraseView();
1746
1747 for( const std::pair<const PAD*, OFFSET>& fpOffset : m_fpOffsets )
1748 {
1749 VECTOR2I offset = fpOffset.second.p_new - fpOffset.second.p_old;
1750 FOOTPRINT* footprint = fpOffset.first->GetParent();
1751 VECTOR2I p_orig = footprint->GetPosition();
1752 VECTOR2I p_new = p_orig + offset;
1753
1754 if( processedFootprints.find( footprint ) != processedFootprints.end() )
1755 continue;
1756
1757 processedFootprints.insert( footprint );
1758 m_commit->Modify( footprint );
1759 footprint->SetPosition( p_new );
1760 }
1761
1762 m_fpOffsets.clear();
1763
1764 m_commit->Push( _( "Interactive Router" ), m_commitFlags );
1765 m_commit = std::make_unique<BOARD_COMMIT>( m_tool );
1766}
1767
1768
1770{
1771 return static_cast<EDA_UNITS>( m_tool->GetManager()->GetSettings()->m_System.units );
1772}
1773
1774
1776{
1777 wxLogTrace( wxT( "PNS" ), wxT( "SetView %p" ), aView );
1778
1779 if( m_previewItems )
1780 {
1782 delete m_previewItems;
1783 }
1784
1785 m_view = aView;
1788
1789 if(m_view)
1791
1792 delete m_debugDecorator;
1793
1794 auto dec = new PNS_PCBNEW_DEBUG_DECORATOR();
1795 m_debugDecorator = dec;
1796
1797 dec->SetDebugEnabled( ADVANCED_CFG::GetCfg().m_ShowRouterDebugGraphics );
1798
1799 if( ADVANCED_CFG::GetCfg().m_ShowRouterDebugGraphics )
1800 dec->SetView( m_view );
1801}
1802
1803
1804void PNS_KICAD_IFACE::UpdateNet( int aNetCode )
1805{
1806 wxLogTrace( wxT( "PNS" ), wxT( "Update-net %d" ), aNetCode );
1807}
1808
1809
1811{
1812 return m_ruleResolver;
1813}
1814
1815
1817{
1818 m_tool = aTool;
1819 m_commit = std::make_unique<BOARD_COMMIT>( m_tool );
1820}
int color
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
@ OFF
Net (and netclass) colors are not shown.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
Container for design settings for a BOARD object.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
bool UseNetClassVia() const
Return true if netclass values should be used to obtain appropriate via size.
BOARD_STACKUP & GetStackupDescriptor()
bool UseNetClassTrack() const
Return true if netclass values should be used to obtain appropriate track width.
bool UseNetClassDiffPair() const
Return true if netclass values should be used to obtain appropriate diff pair dimensions.
bool m_UseHeightForLengthCalcs
Enable inclusion of stackup height in track length measurements and length tuning.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:58
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:180
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition: board_item.h:115
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:245
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:214
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:185
virtual bool IsLocked() const
Definition: board_item.cpp:71
BOARD_ITEM_CONTAINER * GetParentFootprint() const
Definition: board_item.cpp:239
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:163
Manage layers needed to make a physical board.
int GetLayerDistance(PCB_LAYER_ID aFirstLayer, PCB_LAYER_ID aSecondLayer) const
Calculate the distance (height) between the two given copper layers.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
ZONES & Zones()
Definition: board.h:313
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1417
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition: board.cpp:1911
FOOTPRINTS & Footprints()
Definition: board.h:307
TRACKS & Tracks()
Definition: board.h:304
DRAWINGS & Drawings()
Definition: board.h:310
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:643
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:424
wxString GetName() const
Definition: drc_rule.h:147
SEVERITY GetSeverity() const
Definition: drc_rule.h:160
const MINOPTMAX< int > & GetValue() const
Definition: drc_rule.h:139
bool IsNull() const
Definition: drc_rule.h:134
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:143
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
Definition: eda_shape.h:289
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:72
std::shared_ptr< SHAPE_COMPOUND > GetEffectiveTextShape(bool aTriangulate=true, bool aUseTextRotation=true) const
build a list of segments (SHAPE_SEGMENT) to describe a text shape.
Definition: eda_text.cpp:853
void SetPosition(const VECTOR2I &aPos) override
Definition: footprint.cpp:1658
VECTOR2I GetPosition() const override
Definition: footprint.h:188
A specialization of ZONE for use in footprints.
Definition: zone.h:910
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:46
@ KD_WARNING
Definition: confirm.h:49
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:56
int ShowModal() override
Definition: confirm.cpp:100
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
Definition: pcb_painter.h:72
NET_COLOR_MODE GetNetColorMode() const
Definition: pcb_painter.h:111
COLOR4D GetColor(const VIEW_ITEM *aItem, int aLayer) const override
Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer using curr...
std::map< int, KIGFX::COLOR4D > & GetNetColorMap()
Definition: pcb_painter.h:116
std::map< wxString, KIGFX::COLOR4D > & GetNetclassColorMap()
Definition: pcb_painter.h:114
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const std::set< int > & GetHighlightNetCodes() const
Return the netcode of currently highlighted net.
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
bool GetHighContrast() const
Extend VIEW_ITEM by possibility of grouping items into a single object.
Definition: view_group.h:47
void FreeItems()
Free all the items that were added to the group.
Definition: view_group.cpp:191
virtual void SetLayer(int aLayer)
Set layer used to draw the group.
Definition: view_group.h:98
virtual void Add(VIEW_ITEM *aItem)
Add an item to the group.
Definition: view_group.cpp:57
virtual double ViewGetLOD(int aLayer, VIEW *aView) const
Return the level of detail (LOD) of the item.
Definition: view_item.h:132
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:69
double GetScale() const
Definition: view.h:269
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:316
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1586
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:410
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:213
bool IsVisible(const VIEW_ITEM *aItem) const
Return information if the item is visible (or not).
Definition: view.cpp:1564
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1524
Represent a contiguous set of PCB layers.
Definition: pns_layerset.h:32
int Start() const
Definition: pns_layerset.h:82
bool IsMultilayer() const
Definition: pns_layerset.h:77
int End() const
Definition: pns_layerset.h:87
LAYER_RANGE Intersection(const LAYER_RANGE &aOther) const
Shortcut for comparisons/overlap tests.
Definition: pns_layerset.h:108
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:67
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
T Min() const
Definition: minoptmax.h:33
void SetMin(T v)
Definition: minoptmax.h:41
T Opt() const
Definition: minoptmax.h:35
Handle the data for a net.
Definition: netinfo.h:66
const wxString & GetNetname() const
Definition: netinfo.h:119
int GetNetCode() const
Definition: netinfo.h:113
Definition: pad.h:59
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pad.h:392
const VECTOR2I & GetDrillSize() const
Definition: pad.h:262
PAD_ATTRIB GetAttribute() const
Definition: pad.h:395
const VECTOR2I & GetOffset() const
Definition: pad.h:269
VECTOR2I ShapePos() const
Definition: pad.cpp:757
bool IsFreePad() const
Definition: pad.cpp:172
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
Definition: pad.h:365
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING flashPTHPads=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pad.cpp:357
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const override
Return a SHAPE_SEGMENT object representing the pad's hole.
Definition: pad.cpp:394
int GetPadToDieLength() const
Definition: pad.h:408
void SetMid(const VECTOR2I &aMid)
Definition: pcb_track.h:309
const VECTOR2I & GetMid() const
Definition: pcb_track.h:310
void SetWidth(int aWidth)
Definition: pcb_track.h:105
int GetWidth() const
Definition: pcb_track.h:106
void SetEnd(const VECTOR2I &aEnd)
Definition: pcb_track.h:108
void SetStart(const VECTOR2I &aStart)
Definition: pcb_track.h:111
const VECTOR2I & GetStart() const
Definition: pcb_track.h:112
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:109
bool GetIsFree() const
Checks if the via is a free via (as opposed to one created on a track by the router).
Definition: pcb_track.h:540
PCB_LAYER_ID BottomLayer() const
Definition: pcb_track.cpp:570
VECTOR2I GetPosition() const override
Definition: pcb_track.h:438
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: pcb_track.h:512
void SetIsFree(bool aFree=true)
Definition: pcb_track.h:541
void SetPosition(const VECTOR2I &aPoint) override
Definition: pcb_track.h:439
void SetLayerPair(PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer)
Function SetLayerPair For a via m_layer contains the top layer, the other layer is in m_bottomLayer.
Definition: pcb_track.cpp:521
void SetViaType(VIATYPE aViaType)
Definition: pcb_track.h:391
PCB_LAYER_ID TopLayer() const
Definition: pcb_track.cpp:564
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Definition: pcb_track.cpp:192
VIATYPE GetViaType() const
Definition: pcb_track.h:390
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
Definition: pcb_track.cpp:542
int Width() const override
Definition: pns_arc.h:87
const SHAPE * Shape() const override
Return the geometrical shape of the item.
Definition: pns_arc.h:77
void SetDebugEnabled(bool aEnabled)
ITEM_SET & ExcludeItem(const ITEM *aItem)
ITEM_SET & FilterKinds(int aKindMask, bool aInvert=false)
Definition: pns_itemset.cpp:68
ENTRIES & Items()
Definition: pns_itemset.h:135
Base class for PNS router board items.
Definition: pns_item.h:56
BOARD_ITEM * Parent() const
Definition: pns_item.h:151
PnsKind Kind() const
Return the type (kind) of the item.
Definition: pns_item.h:132
NODE * Owner() const
Return the owner of this item, or NULL if there's none.
Definition: pns_item.h:173
virtual int Layer() const
Definition: pns_item.h:160
@ SOLID_T
Definition: pns_item.h:63
@ LINE_T
Definition: pns_item.h:64
@ SEGMENT_T
Definition: pns_item.h:66
void SetParent(BOARD_ITEM *aParent)
Definition: pns_item.h:150
const LAYER_RANGE & Layers() const
Definition: pns_item.h:156
bool OfKind(int aKindMask) const
Return true if the item's type matches the mask aKindMask.
Definition: pns_item.h:140
bool IsVirtual() const
Definition: pns_item.h:240
int Net() const
Definition: pns_item.h:154
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
ITEM_SET & Links()
Definition: pns_joint.h:251
Keep the router "world" - i.e.
Definition: pns_node.h:156
void SetMaxClearance(int aClearance)
Assign a clearance resolution function object.
Definition: pns_node.h:186
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Add an item to the current node.
Definition: pns_node.cpp:664
void SetRuleResolver(RULE_RESOLVER *aFunc)
Definition: pns_node.h:192
void AddEdgeExclusion(std::unique_ptr< SHAPE > aShape)
Definition: pns_node.cpp:728
const SEG & Seg() const
Definition: pns_segment.h:84
int Width() const override
Definition: pns_segment.h:79
void SetTrackWidth(int aWidth)
void SetDiffPairViaGapSameAsTraceGap(bool aEnable)
void SetDiffPairWidth(int aWidth)
void SetDiffPairWidthSource(const wxString &aSource)
void SetDiffPairGapSource(const wxString &aSource)
void SetDiffPairGap(int aGap)
void SetHoleToHole(int aHoleToHole)
void SetViaDrill(int aDrill)
void SetDiffPairViaGap(int aGap)
void SetMinClearance(int aClearance)
void SetViaDiameter(int aDiameter)
void SetClearanceSource(const wxString &aSource)
void SetWidthSource(const wxString &aSource)
void SetTrackWidthIsExplicit(bool aIsExplicit)
bool syncGraphicalItem(PNS::NODE *aWorld, PCB_SHAPE *aItem)
bool inheritTrackWidth(PNS::ITEM *aItem, int *aInheritedWidth)
void AddItem(PNS::ITEM *aItem) override
virtual EDA_UNITS GetUnits() const
bool ImportSizes(PNS::SIZES_SETTINGS &aSizes, PNS::ITEM *aStartItem, int aNet) override
PNS::DEBUG_DECORATOR * m_debugDecorator
void SetDebugDecorator(PNS::DEBUG_DECORATOR *aDec)
bool syncZone(PNS::NODE *aWorld, ZONE *aZone, SHAPE_POLY_SET *aBoardOutline)
void SetBoard(BOARD *aBoard)
std::unique_ptr< PNS::ARC > syncArc(PCB_ARC *aArc)
void RemoveItem(PNS::ITEM *aItem) override
bool syncTextItem(PNS::NODE *aWorld, EDA_TEXT *aText, PCB_LAYER_ID aLayer)
PNS::RULE_RESOLVER * GetRuleResolver() override
bool IsFlashedOnLayer(const PNS::ITEM *aItem, int aLayer) const override
std::unique_ptr< PNS::SOLID > syncPad(PAD *aPad)
void SyncWorld(PNS::NODE *aWorld) override
int StackupHeight(int aFirstLayer, int aSecondLayer) const override
PNS::DEBUG_DECORATOR * GetDebugDecorator() override
std::unique_ptr< PNS::SEGMENT > syncTrack(PCB_TRACK *aTrack)
PNS_PCBNEW_RULE_RESOLVER * m_ruleResolver
std::unique_ptr< PNS::VIA > syncVia(PCB_VIA *aVia)
void UpdateItem(PNS::ITEM *aItem) override
void SetView(KIGFX::VIEW *aView)
void DisplayRatline(const SHAPE_LINE_CHAIN &aRatline, int aNetCode) override
void RemoveItem(PNS::ITEM *aItem) override
void AddItem(PNS::ITEM *aItem) override
void UpdateItem(PNS::ITEM *aItem) override
std::map< PAD *, OFFSET > m_fpOffsets
void SetHostTool(PCB_TOOL_BASE *aTool)
std::unique_ptr< BOARD_COMMIT > m_commit
void UpdateNet(int aNetCode) override
void EraseView() override
void HideItem(PNS::ITEM *aItem) override
KIGFX::VIEW * m_view
bool IsItemVisible(const PNS::ITEM *aItem) const override
std::unordered_set< BOARD_ITEM * > m_hiddenItems
EDA_UNITS GetUnits() const override
bool IsAnyLayerVisible(const LAYER_RANGE &aLayer) const override
PCB_TOOL_BASE * m_tool
void Commit() override
void DisplayItem(const PNS::ITEM *aItem, int aClearance, bool aEdit=false) override
KIGFX::VIEW_GROUP * m_previewItems
PNS_PCBNEW_DEBUG_DECORATOR(KIGFX::VIEW *aView=nullptr)
KIGFX::VIEW_GROUP * m_items
void SetView(KIGFX::VIEW *aView)
virtual void AddPoint(const VECTOR2I &aP, const KIGFX::COLOR4D &aColor, int aSize, const wxString &aName=wxT(""), const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
virtual int HoleToHoleClearance(const PNS::ITEM *aA, const PNS::ITEM *aB, bool aUseClearanceEpsilon=true) override
std::unordered_map< CLEARANCE_CACHE_KEY, int > m_holeToHoleClearanceCache
PNS_PCBNEW_RULE_RESOLVER(BOARD *aBoard, PNS::ROUTER_IFACE *aRouterIface)
virtual bool QueryConstraint(PNS::CONSTRAINT_TYPE aType, const PNS::ITEM *aItemA, const PNS::ITEM *aItemB, int aLayer, PNS::CONSTRAINT *aConstraint) override
virtual wxString NetName(int aNet) override
std::unordered_map< CLEARANCE_CACHE_KEY, int > m_holeClearanceCache
virtual int Clearance(const PNS::ITEM *aA, const PNS::ITEM *aB, bool aUseClearanceEpsilon=true) override
int matchDpSuffix(const wxString &aNetName, wxString &aComplementNet)
Checks for netnamed differential pairs.
void ClearCacheForItem(const PNS::ITEM *aItem) override
virtual int DpCoupledNet(int aNet) override
virtual bool DpNetPair(const PNS::ITEM *aItem, int &aNetP, int &aNetN) override
int holeRadius(const PNS::ITEM *aItem) const
std::unordered_map< CLEARANCE_CACHE_KEY, int > m_clearanceCache
virtual bool IsNetTieExclusion(const PNS::ITEM *aItem, const VECTOR2I &aCollisionPos, const PNS::ITEM *aCollidingItem) override
virtual bool IsInNetTie(const PNS::ITEM *aA) override
virtual int DpNetPolarity(int aNet) override
virtual bool IsDiffPair(const PNS::ITEM *aA, const PNS::ITEM *aB) override
PNS::ROUTER_IFACE * m_routerIface
virtual int HoleClearance(const PNS::ITEM *aA, const PNS::ITEM *aB, bool aUseClearanceEpsilon=true) override
void SetClearance(int aClearance)
void SetColor(const KIGFX::COLOR4D &aColor)
void ShowClearance(bool aEnabled)
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
const VECTOR2I & GetArcMid() const
Definition: shape_arc.h:114
const VECTOR2I & GetP1() const
Definition: shape_arc.h:113
const VECTOR2I & GetP0() const
Definition: shape_arc.h:112
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Clear()
Remove all points from the line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
void GetTriangle(int index, VECTOR2I &a, VECTOR2I &b, VECTOR2I &c) const
Represent a set of closed polygons.
bool IsTriangulationUpToDate() const
void CacheTriangulation(bool aPartition=true, bool aSimplify=false)
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
const TRIANGULATED_POLYGON * TriangulatedPolygon(int aIndex) const
int OutlineCount() const
Return the number of vertices in a given outline/hole.
int GetWidth() const
void SetWidth(int aWidth)
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
Definition: shape_simple.h:42
void Append(int aX, int aY)
Append a new point at the end of the polygon.
Definition: shape_simple.h:135
An abstract shape on 2D plane.
Definition: shape.h:123
TOOL_MANAGER * GetManager() const
Return the instance of TOOL_MANAGER that takes care of the tool.
Definition: tool_base.h:143
APP_SETTINGS_BASE * GetSettings() const
Definition: tool_manager.h:294
VECTOR2_TRAITS< int >::extended_type extended_type
Definition: vector2d.h:76
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:697
bool GetDoNotAllowTracks() const
Definition: zone.h:700
SHAPE_POLY_SET * Outline()
Definition: zone.h:312
wxString GetZoneName() const
Definition: zone.h:124
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.h:122
wxString GetSelectMenuText(UNITS_PROVIDER *aUnitsProvider) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: zone.cpp:777
This file is part of the common library.
DRC_CONSTRAINT_T
Definition: drc_rule.h:44
@ VIA_DIAMETER_CONSTRAINT
Definition: drc_rule.h:62
@ DIFF_PAIR_GAP_CONSTRAINT
Definition: drc_rule.h:65
@ TRACK_WIDTH_CONSTRAINT
Definition: drc_rule.h:55
@ EDGE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:49
@ LENGTH_CONSTRAINT
Definition: drc_rule.h:63
@ CLEARANCE_CONSTRAINT
Definition: drc_rule.h:46
@ HOLE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:47
@ HOLE_SIZE_CONSTRAINT
Definition: drc_rule.h:50
@ HOLE_TO_HOLE_CONSTRAINT
Definition: drc_rule.h:48
#define _(s)
EDA_UNITS
Definition: eda_units.h:43
E_SERIE r
Definition: eserie.cpp:41
@ ALWAYS_FLASHED
#define MAX_CU_LAYERS
Definition: layer_ids.h:140
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:825
@ LAYER_RATSNEST
Definition: layer_ids.h:204
@ LAYER_SELECT_OVERLAY
currently selected items overlay
Definition: layer_ids.h:219
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ PCBNEW_LAYER_ID_START
Definition: layer_ids.h:63
@ Edge_Cuts
Definition: layer_ids.h:113
@ B_Cu
Definition: layer_ids.h:95
@ Margin
Definition: layer_ids.h:114
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
@ PCB_LAYER_ID_COUNT
Definition: layer_ids.h:137
@ F_Cu
Definition: layer_ids.h:64
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
This file contains miscellaneous commonly used macros and functions.
@ APPEARANCE
Visibility flag has changed.
Definition: view_item.h:47
void SetWidth(const wxString &aStr, const wxString &aDefaultMeasurementUnit, int *aWidth, const wxString &aActualConversion)
Push and Shove diff pair dimensions (gap) settings dialog.
CONSTRAINT_TYPE
An abstract function object, returning a design rule (clearance, diff pair gap, etc) required between...
Definition: pns_node.h:55
@ MK_LOCKED
Definition: pns_item.h:43
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:279
Definition: bitmap.cpp:64
@ NPTH
like PAD_PTH, but not plated
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ CONN
Like smd, does not appear on the solder paste layer (default)
@ PAD_DRILL_SHAPE_CIRCLE
Definition: pad_shapes.h:70
@ CASTELLATED
a pad with a castellated through hole
@ SHOW_WITH_VIA_WHILE_ROUTING_OR_DRAGGING
@ SHOW_WHILE_ROUTING
@ SHOW_WITH_VIA_ALWAYS
@ SHOW_WITH_VIA_WHILE_ROUTING
bool isEdge(const PNS::ITEM *aItem)
bool isCopper(const PNS::ITEM *aItem)
VECTOR2I::extended_type ecoord
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
@ RPT_SEVERITY_IGNORE
@ SH_SEGMENT
line segment
Definition: shape.h:45
@ SH_ARC
circular arc
Definition: shape.h:51
@ SH_LINE_CHAIN
line chain (polyline)
Definition: shape.h:46
const PNS::ITEM * A
bool operator==(const CLEARANCE_CACHE_KEY &other) const
const PNS::ITEM * B
wxString m_RuleName
Definition: pns_node.h:72
MINOPTMAX< int > m_Value
Definition: pns_node.h:70
CONSTRAINT_TYPE m_Type
Definition: pns_node.h:69
std::size_t operator()(const CLEARANCE_CACHE_KEY &k) const
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102
@ PCB_FP_TEXTBOX_T
class FP_TEXTBOX, wrapped text in a footprint
Definition: typeinfo.h:93
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:91
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:90
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:103
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:101
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618