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