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