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 ) override;
76  virtual int HoleClearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) override;
77  virtual int HoleToHoleClearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) override;
78 
79  virtual int DpCoupledNet( int aNet ) override;
80  virtual int DpNetPolarity( int aNet ) override;
81  virtual bool DpNetPair( const PNS::ITEM* aItem, int& aNetP, int& aNetN ) override;
82  virtual bool IsDiffPair( const PNS::ITEM* aA, const PNS::ITEM* aB ) override;
83 
84  virtual bool QueryConstraint( PNS::CONSTRAINT_TYPE aType, const PNS::ITEM* aItemA,
85  const PNS::ITEM* aItemB, int aLayer,
86  PNS::CONSTRAINT* aConstraint ) override;
87  virtual wxString NetName( int aNet ) override;
88 
89  int ClearanceEpsilon() const { return m_clearanceEpsilon; }
90 
91  void ClearCacheForItem( const PNS::ITEM* aItem ) override;
92 
93 private:
94  int holeRadius( const PNS::ITEM* aItem ) const;
95 
105  int matchDpSuffix( const wxString& aNetName, wxString& aComplementNet );
106 
107 private:
114 
115  std::map<std::pair<const PNS::ITEM*, const PNS::ITEM*>, int> m_clearanceCache;
116  std::map<std::pair<const PNS::ITEM*, const PNS::ITEM*>, int> m_holeClearanceCache;
117  std::map<std::pair<const PNS::ITEM*, const PNS::ITEM*>, int> m_holeToHoleClearanceCache;
118 };
119 
120 
122  PNS::ROUTER_IFACE* aRouterIface ) :
123  m_routerIface( aRouterIface ),
124  m_board( aBoard ),
125  m_dummyTracks{ { aBoard }, { aBoard } },
126  m_dummyArcs{ { aBoard }, { aBoard } },
127  m_dummyVias{ { aBoard }, { aBoard } }
128 {
129  if( aBoard )
130  m_clearanceEpsilon = aBoard->GetDesignSettings().GetDRCEpsilon();
131  else
132  m_clearanceEpsilon = 0;
133 }
134 
135 
137 {
138 }
139 
140 
142 {
143  if( aItem->Kind() == PNS::ITEM::SOLID_T )
144  {
145  const PAD* pad = dynamic_cast<const PAD*>( aItem->Parent() );
146 
147  if( pad && pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
148  return pad->GetDrillSize().x / 2;
149  }
150  else if( aItem->Kind() == PNS::ITEM::VIA_T )
151  {
152  const PCB_VIA* via = dynamic_cast<const PCB_VIA*>( aItem->Parent() );
153 
154  if( via )
155  return via->GetDrillValue() / 2;
156  }
157 
158  return 0;
159 }
160 
161 
163 {
164  int net_p, net_n;
165 
166  if( !DpNetPair( aA, net_p, net_n ) )
167  return false;
168 
169  if( aA->Net() == net_p && aB->Net() == net_n )
170  return true;
171 
172  if( aB->Net() == net_p && aA->Net() == net_n )
173  return true;
174 
175  return false;
176 }
177 
178 
179 bool isCopper( const PNS::ITEM* aItem )
180 {
181  BOARD_ITEM* parent = aItem->Parent();
182 
183  if( parent && parent->Type() == PCB_PAD_T )
184  {
185  PAD* pad = static_cast<PAD*>( parent );
186  return pad->IsOnCopperLayer() && pad->GetAttribute() != PAD_ATTRIB::NPTH;
187  }
188 
189  return true;
190 }
191 
192 
193 bool isEdge( const PNS::ITEM* aItem )
194 {
195  const BOARD_ITEM *parent = aItem->Parent();
196 
197  if( parent )
198  {
199  return parent->GetLayer() == Edge_Cuts || parent->GetLayer () == Margin;
200  }
201 
202  return false;
203 }
204 
205 
207  const PNS::ITEM* aItemA, const PNS::ITEM* aItemB,
208  int aLayer, PNS::CONSTRAINT* aConstraint )
209 {
210  std::shared_ptr<DRC_ENGINE> drcEngine = m_board->GetDesignSettings().m_DRCEngine;
211 
212  if( !drcEngine )
213  return false;
214 
215  DRC_CONSTRAINT_T hostType;
216 
217  switch ( aType )
218  {
222  case PNS::CONSTRAINT_TYPE::CT_LENGTH: hostType = LENGTH_CONSTRAINT; break;
228  default: return false; // should not happen
229  }
230 
231  BOARD_ITEM* parentA = aItemA ? aItemA->Parent() : nullptr;
232  BOARD_ITEM* parentB = aItemB ? aItemB->Parent() : nullptr;
233  DRC_CONSTRAINT hostConstraint;
234 
235  // A track being routed may not have a BOARD_ITEM associated yet.
236  if( aItemA && !parentA )
237  {
238  switch( aItemA->Kind() )
239  {
240  case PNS::ITEM::ARC_T: parentA = &m_dummyArcs[0]; break;
241  case PNS::ITEM::VIA_T: parentA = &m_dummyVias[0]; break;
242  case PNS::ITEM::SEGMENT_T: parentA = &m_dummyTracks[0]; break;
243  case PNS::ITEM::LINE_T: parentA = &m_dummyTracks[0]; break;
244  default: break;
245  }
246 
247  if( parentA )
248  {
249  parentA->SetLayer( (PCB_LAYER_ID) aLayer );
250  static_cast<BOARD_CONNECTED_ITEM*>( parentA )->SetNetCode( aItemA->Net(), true );
251  }
252  }
253 
254  if( aItemB && !parentB )
255  {
256  switch( aItemB->Kind() )
257  {
258  case PNS::ITEM::ARC_T: parentB = &m_dummyArcs[1]; break;
259  case PNS::ITEM::VIA_T: parentB = &m_dummyVias[1]; break;
260  case PNS::ITEM::SEGMENT_T: parentB = &m_dummyTracks[1]; break;
261  case PNS::ITEM::LINE_T: parentB = &m_dummyTracks[1]; break;
262  default: break;
263  }
264 
265  if( parentB )
266  {
267  parentB->SetLayer( (PCB_LAYER_ID) aLayer );
268  static_cast<BOARD_CONNECTED_ITEM*>( parentB )->SetNetCode( aItemB->Net(), true );
269  }
270  }
271 
272  if( parentA )
273  hostConstraint = drcEngine->EvalRules( hostType, parentA, parentB, (PCB_LAYER_ID) aLayer );
274 
275  if( hostConstraint.IsNull() )
276  return false;
277 
278  switch ( aType )
279  {
288  aConstraint->m_Value = hostConstraint.GetValue();
289  aConstraint->m_RuleName = hostConstraint.GetName();
290  aConstraint->m_Type = aType;
291  return true;
292 
293  default:
294  return false;
295  }
296 }
297 
298 
300 {
301  m_clearanceCache.erase( std::make_pair( aItem, nullptr ) );
302 }
303 
304 
306 {
307  std::pair<const PNS::ITEM*, const PNS::ITEM*> key( aA, aB );
308  auto it = m_clearanceCache.find( key );
309 
310  if( it != m_clearanceCache.end() )
311  return it->second;
312 
313  PNS::CONSTRAINT constraint;
314  int rv = 0;
315  int layer;
316 
317  if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() )
318  layer = aA->Layer();
319  else
320  layer = aB->Layer();
321 
322  if( isCopper( aA ) && ( !aB || isCopper( aB ) ) )
323  {
324  if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_CLEARANCE, aA, aB, layer, &constraint ) )
325  rv = constraint.m_Value.Min() - m_clearanceEpsilon;
326  }
327 
328  if( isEdge( aA ) || ( aB && isEdge( aB ) ) )
329  {
330  if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_EDGE_CLEARANCE, aA, aB, layer, &constraint ) )
331  {
332  if( constraint.m_Value.Min() > rv )
333  rv = constraint.m_Value.Min() - m_clearanceEpsilon;
334  }
335  }
336 
337  m_clearanceCache[ key ] = rv;
338  return rv;
339 }
340 
341 
343 {
344  std::pair<const PNS::ITEM*, const PNS::ITEM*> key( aA, aB );
345  auto it = m_holeClearanceCache.find( key );
346 
347  if( it != m_holeClearanceCache.end() )
348  return it->second;
349 
350  PNS::CONSTRAINT constraint;
351  int rv = 0;
352  int layer;
353 
354  if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() )
355  layer = aA->Layer();
356  else
357  layer = aB->Layer();
358 
359  if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_HOLE_CLEARANCE, aA, aB, layer, &constraint ) )
360  rv = constraint.m_Value.Min() - m_clearanceEpsilon;
361 
362  m_holeClearanceCache[ key ] = rv;
363  return rv;
364 }
365 
366 
368 {
369  std::pair<const PNS::ITEM*, const PNS::ITEM*> key( aA, aB );
370  auto it = m_holeToHoleClearanceCache.find( key );
371 
372  if( it != m_holeToHoleClearanceCache.end() )
373  return it->second;
374 
375  PNS::CONSTRAINT constraint;
376  int rv = 0;
377  int layer;
378 
379  if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() )
380  layer = aA->Layer();
381  else
382  layer = aB->Layer();
383 
384  if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_HOLE_TO_HOLE, aA, aB, layer, &constraint ) )
385  rv = constraint.m_Value.Min() - m_clearanceEpsilon;
386 
387  m_holeToHoleClearanceCache[ key ] = rv;
388  return rv;
389 }
390 
391 
392 bool PNS_KICAD_IFACE_BASE::inheritTrackWidth( PNS::ITEM* aItem, int* aInheritedWidth )
393 {
394  VECTOR2I p;
395 
396  assert( aItem->Owner() != nullptr );
397 
398  auto tryGetTrackWidth =
399  []( PNS::ITEM* aPnsItem ) -> int
400  {
401  switch( aPnsItem->Kind() )
402  {
403  case PNS::ITEM::SEGMENT_T: return static_cast<PNS::SEGMENT*>( aPnsItem )->Width();
404  case PNS::ITEM::ARC_T: return static_cast<PNS::ARC*>( aPnsItem )->Width();
405  default: return -1;
406  }
407  };
408 
409  int itemTrackWidth = tryGetTrackWidth( aItem );
410 
411  if( itemTrackWidth > 0 )
412  {
413  *aInheritedWidth = itemTrackWidth;
414  return true;
415  }
416 
417  switch( aItem->Kind() )
418  {
419  case PNS::ITEM::VIA_T:
420  p = static_cast<PNS::VIA*>( aItem )->Pos();
421  break;
422 
423  case PNS::ITEM::SOLID_T:
424  p = static_cast<PNS::SOLID*>( aItem )->Pos();
425  break;
426 
427  default:
428  return false;
429  }
430 
431  PNS::JOINT* jt = static_cast<PNS::NODE*>( aItem->Owner() )->FindJoint( p, aItem );
432 
433  assert( jt != nullptr );
434 
435  int mval = INT_MAX;
436 
437  PNS::ITEM_SET linkedSegs = jt->Links();
439 
440  for( PNS::ITEM* item : linkedSegs.Items() )
441  {
442  int w = tryGetTrackWidth( item );
443  assert( w > 0 );
444  mval = std::min( w, mval );
445  }
446 
447  if( mval == INT_MAX )
448  return false;
449 
450  *aInheritedWidth = mval;
451  return true;
452 }
453 
454 
456  int aNet )
457 {
459  PNS::CONSTRAINT constraint;
460 
461  if( aStartItem && m_startLayer < 0 )
462  m_startLayer = aStartItem->Layer();
463 
464  aSizes.SetMinClearance( bds.m_MinClearance );
465 
466  int trackWidth = bds.m_TrackMinWidth;
467  bool found = false;
468 
469  if( bds.m_UseConnectedTrackWidth && !bds.m_TempOverrideTrackWidth && aStartItem != nullptr )
470  {
471  found = inheritTrackWidth( aStartItem, &trackWidth );
472 
473  if( found )
474  aSizes.SetWidthSource( _( "existing track" ) );
475  }
476 
477  if( !found && bds.UseNetClassTrack() && aStartItem )
478  {
480  m_startLayer, &constraint ) )
481  {
482  trackWidth = std::max( trackWidth, constraint.m_Value.Opt() );
483  found = true;
484 
485  if( trackWidth == constraint.m_Value.Opt() )
486  aSizes.SetWidthSource( constraint.m_RuleName );
487  else
488  aSizes.SetWidthSource( _( "board minimum width" ) );
489  }
490  }
491 
492  if( !found )
493  {
494  trackWidth = std::max( trackWidth, bds.GetCurrentTrackWidth() );
495 
496  if( bds.UseNetClassTrack() )
497  aSizes.SetWidthSource( _( "netclass 'Default'" ) );
498  else if( trackWidth == bds.GetCurrentTrackWidth() )
499  aSizes.SetWidthSource( _( "user choice" ) );
500  else
501  aSizes.SetWidthSource( _( "board minimum width" ) );
502  }
503 
504  aSizes.SetTrackWidth( trackWidth );
506 
507  int viaDiameter = bds.m_ViasMinSize;
508  int viaDrill = bds.m_MinThroughDrill;
509 
510  if( bds.UseNetClassVia() && aStartItem ) // netclass value
511  {
513  nullptr, m_startLayer, &constraint ) )
514  {
515  viaDiameter = std::max( viaDiameter, constraint.m_Value.Opt() );
516  }
517 
519  m_startLayer, &constraint ) )
520  {
521  viaDrill = std::max( viaDrill, constraint.m_Value.Opt() );
522  }
523  }
524  else
525  {
526  viaDiameter = bds.GetCurrentViaSize();
527  viaDrill = bds.GetCurrentViaDrill();
528  }
529 
530  aSizes.SetViaDiameter( viaDiameter );
531  aSizes.SetViaDrill( viaDrill );
532 
533  int diffPairWidth = bds.m_TrackMinWidth;
534  int diffPairGap = bds.m_MinClearance;
535  int diffPairViaGap = bds.m_MinClearance;
536 
537  found = false;
538 
539  // First try to pick up diff pair width from starting track, if enabled
540  if( bds.m_UseConnectedTrackWidth && aStartItem )
541  found = inheritTrackWidth( aStartItem, &diffPairWidth );
542 
543  // Next, pick up gap from netclass, and width also if we didn't get a starting width above
544  if( bds.UseNetClassDiffPair() && aStartItem )
545  {
547  nullptr, m_startLayer, &constraint ) )
548  {
549  diffPairWidth = std::max( diffPairWidth, constraint.m_Value.Opt() );
550  }
551 
553  nullptr, m_startLayer, &constraint ) )
554  {
555  diffPairGap = std::max( diffPairGap, constraint.m_Value.Opt() );
556  diffPairViaGap = std::max( diffPairViaGap, constraint.m_Value.Opt() );
557  }
558  }
559  else
560  {
561  diffPairWidth = bds.GetCurrentDiffPairWidth();
562  diffPairGap = bds.GetCurrentDiffPairGap();
563  diffPairViaGap = bds.GetCurrentDiffPairViaGap();
564  }
565 
566  aSizes.SetDiffPairWidth( diffPairWidth );
567  aSizes.SetDiffPairGap( diffPairGap );
568  aSizes.SetDiffPairViaGap( diffPairViaGap );
569 
570  int holeToHoleMin = bds.m_HoleToHoleMin;
571  PNS::VIA dummyVia;
572 
574  &dummyVia, UNDEFINED_LAYER, &constraint ) )
575  {
576  holeToHoleMin = constraint.m_Value.Min();
577  }
578 
579  aSizes.SetHoleToHole( holeToHoleMin );
580 
581  return true;
582 }
583 
584 
585 int PNS_KICAD_IFACE_BASE::StackupHeight( int aFirstLayer, int aSecondLayer ) const
586 {
588  return 0;
589 
591 
592  return stackup.GetLayerDistance( ToLAYER_ID( aFirstLayer ), ToLAYER_ID( aSecondLayer ) );
593 }
594 
595 
596 int PNS_PCBNEW_RULE_RESOLVER::matchDpSuffix( const wxString& aNetName, wxString& aComplementNet )
597 {
598  int rv = 0;
599  int count = 0;
600 
601  for( auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
602  {
603  int ch = *it;
604 
605  if( ( ch >= '0' && ch <= '9' ) || ch == '_' )
606  {
607  continue;
608  }
609  else if( ch == '+' )
610  {
611  aComplementNet = "-";
612  rv = 1;
613  }
614  else if( ch == '-' )
615  {
616  aComplementNet = "+";
617  rv = -1;
618  }
619  else if( ch == 'N' )
620  {
621  aComplementNet = "P";
622  rv = -1;
623  }
624  else if ( ch == 'P' )
625  {
626  aComplementNet = "N";
627  rv = 1;
628  }
629  else
630  {
631  break;
632  }
633  }
634 
635  if( rv != 0 && count >= 1 )
636  {
637  aComplementNet = aNetName.Left( aNetName.length() - count ) + aComplementNet
638  + aNetName.Right( count - 1 );
639  }
640 
641  return rv;
642 }
643 
644 
646 {
647  wxString refName = m_board->FindNet( aNet )->GetNetname();
648  wxString coupledNetName;
649 
650  if( matchDpSuffix( refName, coupledNetName ) )
651  {
652  NETINFO_ITEM* net = m_board->FindNet( coupledNetName );
653 
654  if( !net )
655  return -1;
656 
657  return net->GetNetCode();
658  }
659 
660  return -1;
661 }
662 
663 
665 {
666  return m_board->FindNet( aNet )->GetNetname();
667 }
668 
669 
671 {
672  wxString refName = m_board->FindNet( aNet )->GetNetname();
673  wxString dummy1;
674 
675  return matchDpSuffix( refName, dummy1 );
676 }
677 
678 
679 bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( const PNS::ITEM* aItem, int& aNetP, int& aNetN )
680 {
681  if( !aItem || !aItem->Parent() || !aItem->Parent()->IsConnected() )
682  return false;
683 
684  BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem->Parent() );
685  NETINFO_ITEM* netInfo = cItem->GetNet();
686 
687  if( !netInfo )
688  return false;
689 
690  wxString netNameP = netInfo->GetNetname();
691  wxString netNameN, netNameCoupled;
692 
693  int r = matchDpSuffix( netNameP, netNameCoupled );
694 
695  if( r == 0 )
696  {
697  return false;
698  }
699  else if( r == 1 )
700  {
701  netNameN = netNameCoupled;
702  }
703  else
704  {
705  netNameN = netNameP;
706  netNameP = netNameCoupled;
707  }
708 
709  NETINFO_ITEM* netInfoP = m_board->FindNet( netNameP );
710  NETINFO_ITEM* netInfoN = m_board->FindNet( netNameN );
711 
712  if( !netInfoP || !netInfoN )
713  return false;
714 
715  aNetP = netInfoP->GetNetCode();
716  aNetN = netInfoN->GetNetCode();
717 
718  return true;
719 }
720 
721 
723 {
724 public:
726  PNS::DEBUG_DECORATOR(),
727  m_view( nullptr ),
728  m_items( nullptr )
729  {
730  SetView( aView );
731  }
732 
734  {
736  delete m_items;
737  }
738 
739  void SetView( KIGFX::VIEW* aView )
740  {
741  Clear();
742  delete m_items;
743  m_items = nullptr;
744  m_view = aView;
745 
746  if( m_view == nullptr )
747  return;
748 
751  m_view->Add( m_items );
752  }
753 
754  virtual void AddPoint( const VECTOR2I& aP, const COLOR4D& aColor, int aSize,
755  const std::string& aName,
756  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override
757  {
759 
760  l.Append( aP - VECTOR2I( -aSize, -aSize ) );
761  l.Append( aP + VECTOR2I( -aSize, -aSize ) );
762 
763  AddLine( l, aColor, 10000, aName );
764 
765  l.Clear();
766  l.Append( aP - VECTOR2I( aSize, -aSize ) );
767  l.Append( aP + VECTOR2I( aSize, -aSize ) );
768 
769  AddLine( l, aColor, 10000, aName );
770  }
771 
772  virtual void AddBox( const BOX2I& aB, const COLOR4D& aColor, const std::string& aName,
773  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override
774  {
776 
777  VECTOR2I o = aB.GetOrigin();
778  VECTOR2I s = aB.GetSize();
779 
780  l.Append( o );
781  l.Append( o.x + s.x, o.y );
782  l.Append( o.x + s.x, o.y + s.y );
783  l.Append( o.x, o.y + s.y );
784  l.Append( o );
785 
786  AddLine( l, aColor, 10000, aName, aSrcLoc );
787  }
788 
789  virtual void AddSegment( const SEG& aS, const COLOR4D& aColor, const std::string& aName,
790  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override
791  {
793 
794  l.Append( aS.A );
795  l.Append( aS.B );
796 
797  AddLine( l, aColor, 10000, aName, aSrcLoc );
798  }
799 
800 
801  virtual void AddLine( const SHAPE_LINE_CHAIN& aLine, const COLOR4D& aColor,
802  int aWidth, const std::string& aName,
803  const SRC_LOCATION_INFO& aSrcLoc = SRC_LOCATION_INFO() ) override
804  {
805  if( !m_view )
806  return;
807 
808  ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( nullptr, m_view );
809 
810  pitem->SetColor( aColor );
811  pitem->Line( aLine, aWidth );
812 
813  // Should not be needed, as m_items has been passed as a parent group in alloc;
814  m_items->Add( pitem );
815  m_view->Update( m_items );
816  }
817 
818  void Clear() override
819  {
820  if( m_view && m_items )
821  {
822  m_items->FreeItems();
823  m_view->Update( m_items );
824  }
825  }
826 
827 private:
830 };
831 
832 
834 {
835  return m_debugDecorator;
836 }
837 
838 
840 {
841  m_ruleResolver = nullptr;
842  m_board = nullptr;
843  m_world = nullptr;
844  m_debugDecorator = nullptr;
845  m_startLayer = -1;
846 }
847 
848 
850 {
851  m_tool = nullptr;
852  m_view = nullptr;
853  m_previewItems = nullptr;
854  m_dispOptions = nullptr;
855 }
856 
857 
859 {
860 }
861 
862 
864 {
865  delete m_ruleResolver;
866  delete m_debugDecorator;
867 
868  if( m_previewItems )
869  {
871  delete m_previewItems;
872  }
873 }
874 
875 
876 std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( PAD* aPad )
877 {
878  LAYER_RANGE layers( 0, MAX_CU_LAYERS - 1 );
879 
880  // ignore non-copper pads except for those with holes
881  if( ( aPad->GetLayerSet() & LSET::AllCuMask() ).none() && aPad->GetDrillSize().x == 0 )
882  return nullptr;
883 
884  switch( aPad->GetAttribute() )
885  {
886  case PAD_ATTRIB::PTH:
887  case PAD_ATTRIB::NPTH:
888  break;
889 
890  case PAD_ATTRIB::CONN:
891  case PAD_ATTRIB::SMD:
892  {
893  LSET lmsk = aPad->GetLayerSet();
894  bool is_copper = false;
895 
896  for( int i = 0; i < MAX_CU_LAYERS; i++ )
897  {
898  if( lmsk[i] )
899  {
900  is_copper = true;
901 
902  if( aPad->GetAttribute() != PAD_ATTRIB::NPTH )
903  layers = LAYER_RANGE( i );
904 
905  break;
906  }
907  }
908 
909  if( !is_copper )
910  return nullptr;
911 
912  break;
913  }
914 
915  default:
916  wxLogTrace( "PNS", "unsupported pad type 0x%x", aPad->GetAttribute() );
917  return nullptr;
918  }
919 
920  std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
921 
922  if( aPad->GetAttribute() == PAD_ATTRIB::NPTH )
923  solid->SetRoutable( false );
924 
925  solid->SetLayers( layers );
926  solid->SetNet( aPad->GetNetCode() );
927  solid->SetParent( aPad );
928  solid->SetPadToDie( aPad->GetPadToDieLength() );
929  solid->SetOrientation( aPad->GetOrientation() );
930 
931  wxPoint wx_c = aPad->ShapePos();
932  wxPoint offset = aPad->GetOffset();
933 
934  VECTOR2I c( wx_c.x, wx_c.y );
935 
936  RotatePoint( &offset, aPad->GetOrientation() );
937 
938  solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) );
939  solid->SetOffset( VECTOR2I( offset.x, offset.y ) );
940 
941  if( aPad->GetDrillSize().x > 0 )
942  {
944 
945  if( aPad->GetAttribute() != PAD_ATTRIB::NPTH )
946  {
948  slot->SetWidth( slot->GetWidth() + bds.GetHolePlatingThickness() * 2 );
949  }
950 
951  solid->SetHole( slot );
952  }
953 
954  std::shared_ptr<SHAPE> shape = aPad->GetEffectiveShape();
955 
956  if( shape->HasIndexableSubshapes() && shape->GetIndexableSubshapeCount() == 1 )
957  {
958  std::vector<SHAPE*> subshapes;
959  shape->GetIndexableSubshapes( subshapes );
960 
961  solid->SetShape( subshapes[0]->Clone() );
962  }
963  else
964  {
965  solid->SetShape( shape->Clone() );
966  }
967 
968  return solid;
969 }
970 
971 
972 std::unique_ptr<PNS::SEGMENT> PNS_KICAD_IFACE_BASE::syncTrack( PCB_TRACK* aTrack )
973 {
974  auto segment = std::make_unique<PNS::SEGMENT>( SEG( aTrack->GetStart(), aTrack->GetEnd() ),
975  aTrack->GetNetCode() );
976 
977  segment->SetWidth( aTrack->GetWidth() );
978  segment->SetLayers( LAYER_RANGE( aTrack->GetLayer() ) );
979  segment->SetParent( aTrack );
980 
981  if( aTrack->IsLocked() )
982  segment->Mark( PNS::MK_LOCKED );
983 
984  return segment;
985 }
986 
987 
988 std::unique_ptr<PNS::ARC> PNS_KICAD_IFACE_BASE::syncArc( PCB_ARC* aArc )
989 {
990  auto arc = std::make_unique<PNS::ARC>(
991  SHAPE_ARC( aArc->GetStart(), aArc->GetMid(), aArc->GetEnd(), aArc->GetWidth() ),
992  aArc->GetNetCode() );
993 
994  arc->SetLayers( LAYER_RANGE( aArc->GetLayer() ) );
995  arc->SetParent( aArc );
996 
997  if( aArc->IsLocked() )
998  arc->Mark( PNS::MK_LOCKED );
999 
1000  return arc;
1001 }
1002 
1003 
1004 std::unique_ptr<PNS::VIA> PNS_KICAD_IFACE_BASE::syncVia( PCB_VIA* aVia )
1005 {
1006  PCB_LAYER_ID top, bottom;
1007  aVia->LayerPair( &top, &bottom );
1008 
1009  auto via = std::make_unique<PNS::VIA>( aVia->GetPosition(),
1010  LAYER_RANGE( aVia->TopLayer(), aVia->BottomLayer() ),
1011  aVia->GetWidth(),
1012  aVia->GetDrillValue(),
1013  aVia->GetNetCode(),
1014  aVia->GetViaType() );
1015 
1016  via->SetParent( aVia );
1017 
1018  if( aVia->IsLocked() )
1019  via->Mark( PNS::MK_LOCKED );
1020 
1021  via->SetIsFree( aVia->GetIsFree() );
1022 
1024  via->SetHole( SHAPE_CIRCLE( aVia->GetPosition(),
1025  aVia->GetDrillValue() / 2 + bds.GetHolePlatingThickness() ) );
1026 
1027  return via;
1028 }
1029 
1030 
1031 bool PNS_KICAD_IFACE_BASE::syncZone( PNS::NODE* aWorld, ZONE* aZone, SHAPE_POLY_SET* aBoardOutline )
1032 {
1033  SHAPE_POLY_SET* poly;
1034 
1035  if( !aZone->GetIsRuleArea() && aZone->GetZoneName().IsEmpty() )
1036  return false;
1037 
1038  // Required by expression function insideArea()
1039  aZone->CacheBoundingBox();
1040 
1041  // TODO handle aZone->GetDoNotAllowVias()
1042  // TODO handle rules which disallow tracks & vias
1043  if( !aZone->GetIsRuleArea() || !aZone->GetDoNotAllowTracks() )
1044  return false;
1045 
1046  LSET layers = aZone->GetLayerSet();
1047  EDA_UNITS units = EDA_UNITS::MILLIMETRES; // TODO: get real units
1048 
1049  poly = aZone->Outline();
1050  poly->CacheTriangulation( false );
1051 
1052  if( !poly->IsTriangulationUpToDate() )
1053  {
1054  KIDIALOG dlg( nullptr, wxString::Format( _( "%s is malformed." ),
1055  aZone->GetSelectMenuText( units ) ),
1057  dlg.ShowDetailedText( wxString::Format( _( "This zone cannot be handled by the router.\n"
1058  "Please verify it is not a self-intersecting "
1059  "polygon." ) ) );
1060  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1061  dlg.ShowModal();
1062 
1063  return false;
1064  }
1065 
1066  for( int layer = F_Cu; layer <= B_Cu; layer++ )
1067  {
1068  if( !layers[ layer ] )
1069  continue;
1070 
1071  for( int outline = 0; outline < poly->OutlineCount(); outline++ )
1072  {
1073  const SHAPE_POLY_SET::TRIANGULATED_POLYGON* tri = poly->TriangulatedPolygon( outline );
1074 
1075  for( size_t i = 0; i < tri->GetTriangleCount(); i++)
1076  {
1077  VECTOR2I a, b, c;
1078  tri->GetTriangle( i, a, b, c );
1079  SHAPE_SIMPLE* triShape = new SHAPE_SIMPLE;
1080 
1081  triShape->Append( a );
1082  triShape->Append( b );
1083  triShape->Append( c );
1084 
1085  std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
1086 
1087  solid->SetLayer( layer );
1088  solid->SetNet( -1 );
1089  solid->SetParent( aZone );
1090  solid->SetShape( triShape );
1091  solid->SetIsCompoundShapePrimitive();
1092  solid->SetRoutable( false );
1093 
1094  aWorld->Add( std::move( solid ) );
1095  }
1096  }
1097  }
1098 
1099  return true;
1100 }
1101 
1102 
1104 {
1105  if( !IsCopperLayer( aLayer ) )
1106  return false;
1107 
1108  int textWidth = aText->GetEffectiveTextPenWidth();
1109  std::vector<wxPoint> textShape = aText->TransformToSegmentList();
1110 
1111  if( textShape.size() < 2 )
1112  return false;
1113 
1114  for( size_t jj = 0; jj < textShape.size(); jj += 2 )
1115  {
1116  VECTOR2I start( textShape[jj] );
1117  VECTOR2I end( textShape[jj+1] );
1118  std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
1119 
1120  solid->SetLayer( aLayer );
1121  solid->SetNet( -1 );
1122  solid->SetParent( dynamic_cast<BOARD_ITEM*>( aText ) );
1123  solid->SetShape( new SHAPE_SEGMENT( start, end, textWidth ) );
1124  solid->SetIsCompoundShapePrimitive();
1125  solid->SetRoutable( false );
1126 
1127  aWorld->Add( std::move( solid ) );
1128  }
1129 
1130  return true;
1131 
1132  /* A coarser (but faster) method:
1133  *
1134  SHAPE_POLY_SET outline;
1135  SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
1136 
1137  aText->TransformBoundingBoxWithClearanceToPolygon( &outline, 0 );
1138 
1139  for( auto iter = outline.CIterate( 0 ); iter; iter++ )
1140  shape->Append( *iter );
1141 
1142  solid->SetShape( shape );
1143 
1144  solid->SetLayer( aLayer );
1145  solid->SetNet( -1 );
1146  solid->SetParent( nullptr );
1147  solid->SetRoutable( false );
1148  aWorld->Add( std::move( solid ) );
1149  return true;
1150  */
1151 }
1152 
1153 
1155 {
1156  if( aItem->GetLayer() == Edge_Cuts
1157  || aItem->GetLayer() == Margin
1158  || IsCopperLayer( aItem->GetLayer() ) )
1159  {
1160  // TODO: where do we handle filled polygons on copper layers?
1161  if( aItem->GetShape() == SHAPE_T::POLY && aItem->IsFilled() )
1162  return false;
1163 
1164  std::vector<SHAPE*> shapes = aItem->MakeEffectiveShapes();
1165 
1166  for( SHAPE* shape : shapes )
1167  {
1168  std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
1169 
1170  if( aItem->GetLayer() == Edge_Cuts || aItem->GetLayer() == Margin )
1171  solid->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) );
1172  else
1173  solid->SetLayer( aItem->GetLayer() );
1174 
1175  if( aItem->GetLayer() == Edge_Cuts )
1176  {
1177  switch( shape->Type() )
1178  {
1179  case SH_SEGMENT: static_cast<SHAPE_SEGMENT*>( shape )->SetWidth( 0 ); break;
1180  case SH_ARC: static_cast<SHAPE_ARC*>( shape )->SetWidth( 0 ); break;
1181  case SH_LINE_CHAIN: static_cast<SHAPE_LINE_CHAIN*>( shape )->SetWidth( 0 ); break;
1182  default: /* remaining shapes don't have width */ break;
1183  }
1184  }
1185 
1186  solid->SetNet( -1 );
1187  solid->SetParent( aItem );
1188  solid->SetShape( shape ); // takes ownership
1189 
1190  if( shapes.size() > 1 )
1191  solid->SetIsCompoundShapePrimitive();
1192 
1193  solid->SetRoutable( false );
1194 
1195  aWorld->Add( std::move( solid ) );
1196  }
1197 
1198  return true;
1199  }
1200 
1201  return false;
1202 }
1203 
1204 
1206 {
1207  m_board = aBoard;
1208  wxLogTrace( "PNS", "m_board = %p", m_board );
1209 }
1210 
1211 
1213 {
1214  if( !m_view )
1215  return false;
1216 
1217  for( int i = aLayer.Start(); i <= aLayer.End(); i++ )
1218  {
1219  if( m_view->IsLayerVisible( i ) )
1220  return true;
1221  }
1222 
1223  return false;
1224 }
1225 
1226 
1227 bool PNS_KICAD_IFACE::IsFlashedOnLayer( const PNS::ITEM* aItem, int aLayer ) const
1228 {
1230  if( aLayer < 0 )
1231  return true;
1232 
1233  if( aItem->Parent() )
1234  {
1235  switch( aItem->Parent()->Type() )
1236  {
1237  case PCB_VIA_T:
1238  {
1239  const PCB_VIA* via = static_cast<const PCB_VIA*>( aItem->Parent() );
1240 
1241  return via->FlashLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
1242  }
1243 
1244  case PCB_PAD_T:
1245  {
1246  const PAD* pad = static_cast<const PAD*>( aItem->Parent() );
1247 
1248  return pad->FlashLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
1249  }
1250 
1251  default:
1252  break;
1253  }
1254  }
1255 
1256  return aItem->Layers().Overlaps( aLayer );
1257 }
1258 
1259 
1260 bool PNS_KICAD_IFACE::IsItemVisible( const PNS::ITEM* aItem ) const
1261 {
1262  // by default, all items are visible (new ones created by the router have parent == NULL
1263  // as they have not been committed yet to the BOARD)
1264  if( !m_view || !aItem->Parent() )
1265  return true;
1266 
1267  BOARD_ITEM* item = aItem->Parent();
1268  bool isOnVisibleLayer = true;
1269  RENDER_SETTINGS* settings = m_view->GetPainter()->GetSettings();
1270 
1271  if( settings->GetHighContrast() )
1272  isOnVisibleLayer = item->IsOnLayer( settings->GetPrimaryHighContrastLayer() );
1273 
1274  if( m_view->IsVisible( item ) && isOnVisibleLayer
1275  && item->ViewGetLOD( item->GetLayer(), m_view ) < m_view->GetScale() )
1276  {
1277  return true;
1278  }
1279 
1280  // Items hidden in the router are not hidden on the board
1281  if( m_hiddenItems.find( item ) != m_hiddenItems.end() )
1282  return true;
1283 
1284  return false;
1285 }
1286 
1287 
1289 {
1290  if( !m_board )
1291  {
1292  wxLogTrace( "PNS", "No board attached, aborting sync." );
1293  return;
1294  }
1295 
1296  int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
1297 
1298  m_world = aWorld;
1299 
1300  for( BOARD_ITEM* gitem : m_board->Drawings() )
1301  {
1302  if ( gitem->Type() == PCB_SHAPE_T )
1303  {
1304  syncGraphicalItem( aWorld, static_cast<PCB_SHAPE*>( gitem ) );
1305  }
1306  else if( gitem->Type() == PCB_TEXT_T )
1307  {
1308  syncTextItem( aWorld, static_cast<PCB_TEXT*>( gitem ), gitem->GetLayer() );
1309  }
1310  }
1311 
1312  SHAPE_POLY_SET buffer;
1313  SHAPE_POLY_SET* boardOutline = nullptr;
1314 
1315  if( m_board->GetBoardPolygonOutlines( buffer ) )
1316  boardOutline = &buffer;
1317 
1318  for( ZONE* zone : m_board->Zones() )
1319  {
1320  syncZone( aWorld, zone, boardOutline );
1321  }
1322 
1323  for( FOOTPRINT* footprint : m_board->Footprints() )
1324  {
1325  for( PAD* pad : footprint->Pads() )
1326  {
1327  if( std::unique_ptr<PNS::SOLID> solid = syncPad( pad ) )
1328  aWorld->Add( std::move( solid ) );
1329 
1330  worstClearance = std::max( worstClearance, pad->GetLocalClearance() );
1331  }
1332 
1333  syncTextItem( aWorld, &footprint->Reference(), footprint->Reference().GetLayer() );
1334  syncTextItem( aWorld, &footprint->Value(), footprint->Value().GetLayer() );
1335 
1336  for( FP_ZONE* zone : footprint->Zones() )
1337  syncZone( aWorld, zone, boardOutline );
1338 
1339  if( footprint->IsNetTie() )
1340  continue;
1341 
1342  for( BOARD_ITEM* mgitem : footprint->GraphicalItems() )
1343  {
1344  if( mgitem->Type() == PCB_FP_SHAPE_T )
1345  {
1346  syncGraphicalItem( aWorld, static_cast<PCB_SHAPE*>( mgitem ) );
1347  }
1348  else if( mgitem->Type() == PCB_FP_TEXT_T )
1349  {
1350  syncTextItem( aWorld, static_cast<FP_TEXT*>( mgitem ), mgitem->GetLayer() );
1351  }
1352  }
1353  }
1354 
1355  for( PCB_TRACK* t : m_board->Tracks() )
1356  {
1357  KICAD_T type = t->Type();
1358 
1359  if( type == PCB_TRACE_T )
1360  {
1361  if( auto segment = syncTrack( t ) )
1362  aWorld->Add( std::move( segment ) );
1363  }
1364  else if( type == PCB_ARC_T )
1365  {
1366  if( auto arc = syncArc( static_cast<PCB_ARC*>( t ) ) )
1367  aWorld->Add( std::move( arc ) );
1368  }
1369  else if( type == PCB_VIA_T )
1370  {
1371  if( auto via = syncVia( static_cast<PCB_VIA*>( t ) ) )
1372  aWorld->Add( std::move( via ) );
1373  }
1374  }
1375 
1376  // NB: if this were ever to become a long-lived object we would need to dirty its
1377  // clearance cache here....
1378  delete m_ruleResolver;
1380 
1381  aWorld->SetRuleResolver( m_ruleResolver );
1382  aWorld->SetMaxClearance( worstClearance + m_ruleResolver->ClearanceEpsilon() );
1383 }
1384 
1385 
1387 {
1388  for( auto item : m_hiddenItems )
1389  m_view->SetVisible( item, true );
1390 
1391  m_hiddenItems.clear();
1392 
1393  if( m_previewItems )
1394  {
1397  }
1398 
1399  if( m_debugDecorator )
1401 }
1402 
1403 
1405 {
1406  m_debugDecorator = aDec;
1407 }
1408 
1409 
1410 void PNS_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit )
1411 {
1412  if( aItem->IsVirtual() )
1413  return;
1414 
1415  ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_view );
1416 
1417  // Note: SEGMENT_T is used for placed tracks; LINE_T is used for the routing head
1419  static int tracksOrVias = tracks | PNS::ITEM::VIA_T;
1420 
1421  if( aClearance >= 0 )
1422  {
1423  pitem->SetClearance( aClearance );
1424 
1426  {
1429  pitem->ShowClearance( aItem->OfKind( tracksOrVias ) );
1430  break;
1431 
1433  pitem->ShowClearance( aItem->OfKind( tracksOrVias ) && !aEdit );
1434  break;
1435 
1437  pitem->ShowClearance( aItem->OfKind( tracks ) && !aEdit );
1438  break;
1439 
1440  default:
1441  pitem->ShowClearance( false );
1442  break;
1443  }
1444  }
1445 
1446  m_previewItems->Add( pitem );
1448 }
1449 
1450 
1451 void PNS_KICAD_IFACE::DisplayRatline( const SHAPE_LINE_CHAIN& aRatline, int aColor )
1452 {
1453  ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( nullptr, m_view );
1454  pitem->Line( aRatline, 10000, aColor );
1455  m_previewItems->Add( pitem );
1457 }
1458 
1459 
1461 {
1462  BOARD_ITEM* parent = aItem->Parent();
1463 
1464  if( parent )
1465  {
1466  if( m_view->IsVisible( parent ) )
1467  m_hiddenItems.insert( parent );
1468 
1469  m_view->SetVisible( parent, false );
1470  m_view->Update( parent, KIGFX::APPEARANCE );
1471  }
1472 }
1473 
1474 
1476 {
1477 }
1478 
1479 
1481 {
1482  BOARD_ITEM* parent = aItem->Parent();
1483 
1484  if( aItem->OfKind( PNS::ITEM::SOLID_T ) )
1485  {
1486  PAD* pad = static_cast<PAD*>( parent );
1487  VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
1488 
1489  m_fpOffsets[ pad ].p_old = pos;
1490  return;
1491  }
1492 
1493  if( parent )
1494  {
1495  m_commit->Remove( parent );
1496  }
1497 }
1498 
1499 
1501 {
1502 }
1503 
1504 
1506 {
1507  BOARD_ITEM* board_item = aItem->Parent();
1508 
1509  m_commit->Modify( board_item );
1510 
1511  switch( aItem->Kind() )
1512  {
1513  case PNS::ITEM::ARC_T:
1514  {
1515  PNS::ARC* arc = static_cast<PNS::ARC*>( aItem );
1516  PCB_ARC* arc_board = static_cast<PCB_ARC*>( board_item );
1517  const SHAPE_ARC* arc_shape = static_cast<const SHAPE_ARC*>( arc->Shape() );
1518  arc_board->SetStart( wxPoint( arc_shape->GetP0() ) );
1519  arc_board->SetEnd( wxPoint( arc_shape->GetP1() ) );
1520  arc_board->SetMid( wxPoint( arc_shape->GetArcMid() ) );
1521  arc_board->SetWidth( arc->Width() );
1522  break;
1523  }
1524 
1525  case PNS::ITEM::SEGMENT_T:
1526  {
1527  PNS::SEGMENT* seg = static_cast<PNS::SEGMENT*>( aItem );
1528  PCB_TRACK* track = static_cast<PCB_TRACK*>( board_item );
1529  const SEG& s = seg->Seg();
1530  track->SetStart( wxPoint( s.A.x, s.A.y ) );
1531  track->SetEnd( wxPoint( s.B.x, s.B.y ) );
1532  track->SetWidth( seg->Width() );
1533  break;
1534  }
1535 
1536  case PNS::ITEM::VIA_T:
1537  {
1538  PCB_VIA* via_board = static_cast<PCB_VIA*>( board_item );
1539  PNS::VIA* via = static_cast<PNS::VIA*>( aItem );
1540  via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) );
1541  via_board->SetWidth( via->Diameter() );
1542  via_board->SetDrill( via->Drill() );
1543  via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 );
1544  via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
1545  via_board->SetIsFree( via->IsFree() );
1546  via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
1547  ToLAYER_ID( via->Layers().End() ) );
1548  break;
1549  }
1550 
1551  case PNS::ITEM::SOLID_T:
1552  {
1553  PAD* pad = static_cast<PAD*>( aItem->Parent() );
1554  VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
1555 
1556  m_fpOffsets[ pad ].p_old = pad->GetPosition();
1557  m_fpOffsets[ pad ].p_new = pos;
1558  break;
1559  }
1560 
1561  default:
1562  break;
1563  }
1564 }
1565 
1566 
1568 {
1569 
1570 }
1571 
1572 
1574 {
1575  BOARD_CONNECTED_ITEM* newBI = nullptr;
1576 
1577  switch( aItem->Kind() )
1578  {
1579  case PNS::ITEM::ARC_T:
1580  {
1581  PNS::ARC* arc = static_cast<PNS::ARC*>( aItem );
1582  PCB_ARC* new_arc = new PCB_ARC( m_board, static_cast<const SHAPE_ARC*>( arc->Shape() ) );
1583  new_arc->SetWidth( arc->Width() );
1584  new_arc->SetLayer( ToLAYER_ID( arc->Layers().Start() ) );
1585  new_arc->SetNetCode( std::max<int>( 0, arc->Net() ) );
1586  newBI = new_arc;
1587  break;
1588  }
1589 
1590  case PNS::ITEM::SEGMENT_T:
1591  {
1592  PNS::SEGMENT* seg = static_cast<PNS::SEGMENT*>( aItem );
1593  PCB_TRACK* track = new PCB_TRACK( m_board );
1594  const SEG& s = seg->Seg();
1595  track->SetStart( wxPoint( s.A.x, s.A.y ) );
1596  track->SetEnd( wxPoint( s.B.x, s.B.y ) );
1597  track->SetWidth( seg->Width() );
1598  track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) );
1599  track->SetNetCode( seg->Net() > 0 ? seg->Net() : 0 );
1600  newBI = track;
1601  break;
1602  }
1603 
1604  case PNS::ITEM::VIA_T:
1605  {
1606  PCB_VIA* via_board = new PCB_VIA( m_board );
1607  PNS::VIA* via = static_cast<PNS::VIA*>( aItem );
1608  via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) );
1609  via_board->SetWidth( via->Diameter() );
1610  via_board->SetDrill( via->Drill() );
1611  via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 );
1612  via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
1613  via_board->SetIsFree( via->IsFree() );
1614  via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
1615  ToLAYER_ID( via->Layers().End() ) );
1616  newBI = via_board;
1617  break;
1618  }
1619 
1620  case PNS::ITEM::SOLID_T:
1621  {
1622  PAD* pad = static_cast<PAD*>( aItem->Parent() );
1623  VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
1624 
1625  m_fpOffsets[ pad ].p_new = pos;
1626  return;
1627  }
1628 
1629  default:
1630  break;
1631  }
1632 
1633  if( newBI )
1634  {
1635  //newBI->SetLocalRatsnestVisible( m_dispOptions->m_ShowGlobalRatsnest );
1636  aItem->SetParent( newBI );
1637  newBI->ClearFlags();
1638 
1639  m_commit->Add( newBI );
1640  }
1641 }
1642 
1643 
1645 {
1646  std::set<FOOTPRINT*> processedFootprints;
1647 
1648  EraseView();
1649 
1650  for( auto fpOffset : m_fpOffsets )
1651  {
1652  VECTOR2I offset = fpOffset.second.p_new - fpOffset.second.p_old;
1653  FOOTPRINT* footprint = fpOffset.first->GetParent();
1654 
1655  VECTOR2I p_orig = footprint->GetPosition();
1656  VECTOR2I p_new = p_orig + offset;
1657 
1658  if( processedFootprints.find( footprint ) != processedFootprints.end() )
1659  continue;
1660 
1661  processedFootprints.insert( footprint );
1662  m_commit->Modify( footprint );
1663  footprint->SetPosition( wxPoint( p_new.x, p_new.y ) );
1664  }
1665 
1666  m_fpOffsets.clear();
1667 
1668  m_commit->Push( _( "Interactive Router" ) );
1669  m_commit = std::make_unique<BOARD_COMMIT>( m_tool );
1670 }
1671 
1672 
1674 {
1675  wxLogTrace( "PNS", "SetView %p", aView );
1676 
1677  if( m_previewItems )
1678  {
1680  delete m_previewItems;
1681  }
1682 
1683  m_view = aView;
1686 
1687  if(m_view)
1689 
1690  delete m_debugDecorator;
1691 
1692  auto dec = new PNS_PCBNEW_DEBUG_DECORATOR();
1693  m_debugDecorator = dec;
1694 
1695  dec->SetDebugEnabled( ADVANCED_CFG::GetCfg().m_ShowRouterDebugGraphics );
1696 
1697  if( ADVANCED_CFG::GetCfg().m_ShowRouterDebugGraphics )
1698  dec->SetView( m_view );
1699 }
1700 
1701 
1702 void PNS_KICAD_IFACE::UpdateNet( int aNetCode )
1703 {
1704  wxLogTrace( "PNS", "Update-net %d", aNetCode );
1705 
1706 }
1707 
1708 
1710 {
1711  return m_ruleResolver;
1712 }
1713 
1714 
1716 {
1717  m_tool = aTool;
1718  m_commit = std::make_unique<BOARD_COMMIT>( m_tool );
1719 }
1720 
1721 
1723 {
1724  m_dispOptions = aDispOptions;
1725 }
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:1325
bool UseNetClassTrack() const
Return true if netclass values should be used to obtain appropriate track width.
virtual int HoleToHoleClearance(const PNS::ITEM *aA, const PNS::ITEM *aB) override
int holeRadius(const PNS::ITEM *aItem) const
currently selected items overlay
Definition: layer_ids.h:215
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:146
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:1880
ZONES & Zones()
Definition: board.h:240
bool syncGraphicalItem(PNS::NODE *aWorld, PCB_SHAPE *aItem)
wxPoint GetPosition() const override
Definition: pcb_track.h:390
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:733
virtual void AddPoint(const VECTOR2I &aP, const COLOR4D &aColor, int aSize, const std::string &aName, const SRC_LOCATION_INFO &aSrcLoc=SRC_LOCATION_INFO()) override
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:163
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:453
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:352
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:603
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
std::map< std::pair< const PNS::ITEM *, const PNS::ITEM * >, int > m_clearanceCache
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:295
std::vector< SHAPE * > MakeEffectiveShapes() const
Make a set of SHAPE objects representing the EDA_SHAPE.
Definition: eda_shape.cpp:1073
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:319
T Opt() const
Definition: minoptmax.h:35
std::map< std::pair< const PNS::ITEM *, const PNS::ITEM * >, int > m_holeToHoleClearanceCache
void SetPosition(const wxPoint &aPoint) override
Definition: pcb_track.h:391
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:174
void HideItem(PNS::ITEM *aItem) override
VECTOR2< int > VECTOR2I
Definition: vector2d.h:622
PCB_LAYER_ID BottomLayer() const
Definition: pcb_track.cpp:462
std::map< std::pair< const PNS::ITEM *, const PNS::ITEM * >, int > m_holeClearanceCache
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
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:81
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:168
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:228
const wxPoint & GetOffset() const
Definition: pad.h:250
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
virtual int HoleClearance(const PNS::ITEM *aA, const PNS::ITEM *aB) override
const wxSize & GetDrillSize() const
Definition: pad.h:243
wxPoint ShapePos() const
Definition: pad.cpp:689
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:192
PCB_LAYER_ID TopLayer() const
Definition: pcb_track.cpp:456
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:505
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:200
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:270
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:736
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)
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pad.cpp:310
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:353
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:797
bool IsNull() const
Definition: drc_rule.h:117
void SetBoard(BOARD *aBoard)
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
virtual int Clearance(const PNS::ITEM *aA, const PNS::ITEM *aB) override
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:482
const MINOPTMAX< int > & GetValue() const
Definition: drc_rule.h:122
void CacheBoundingBox()
Definition: zone.h:146
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:481
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)
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:92
PNS_PCBNEW_RULE_RESOLVER * m_ruleResolver
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:870
Definition: pad.h:57
void SetPosition(const wxPoint &aPos) override
Definition: footprint.cpp:1561
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:135
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:142
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:271
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:639
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:945
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