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