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 <fp_text.h>
25 #include <footprint.h>
26 #include <track.h>
27 #include <zone.h>
28 #include <pcb_shape.h>
29 #include <pcb_text.h>
30 #include <board_commit.h>
32 #include <geometry/convex_hull.h>
33 #include <confirm.h>
34 
35 #include <view/view.h>
36 #include <view/view_item.h>
37 #include <view/view_group.h>
38 
39 #include <pcb_painter.h>
40 
41 #include <geometry/shape.h>
43 #include <geometry/shape_arc.h>
44 #include <geometry/shape_simple.h>
45 
46 #include <drc/drc_rule.h>
47 #include <drc/drc_engine.h>
48 
49 #include <memory>
50 
51 #include <advanced_config.h>
52 
53 #include "tools/pcb_tool_base.h"
54 
55 #include "pns_kicad_iface.h"
56 
57 #include "pns_arc.h"
58 #include "pns_routing_settings.h"
59 #include "pns_sizes_settings.h"
60 #include "pns_item.h"
61 #include "pns_solid.h"
62 #include "pns_segment.h"
63 #include "pns_node.h"
64 #include "pns_router.h"
65 #include "pns_debug_decorator.h"
66 #include "router_preview_item.h"
67 
69 
71 {
72 public:
73  PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER_IFACE* aRouterIface );
74  virtual ~PNS_PCBNEW_RULE_RESOLVER();
75 
76  virtual int Clearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) override;
77  virtual int HoleClearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) override;
78  virtual int HoleToHoleClearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) override;
79 
80  virtual int DpCoupledNet( int aNet ) override;
81  virtual int DpNetPolarity( int aNet ) override;
82  virtual bool DpNetPair( const PNS::ITEM* aItem, int& aNetP, int& aNetN ) override;
83  virtual bool IsDiffPair( const PNS::ITEM* aA, const PNS::ITEM* aB ) override;
84 
85  virtual bool QueryConstraint( PNS::CONSTRAINT_TYPE aType, const PNS::ITEM* aItemA,
86  const PNS::ITEM* aItemB, int aLayer,
87  PNS::CONSTRAINT* aConstraint ) override;
88  virtual wxString NetName( int aNet ) override;
89 
90 private:
91  int holeRadius( const PNS::ITEM* aItem ) const;
92  int matchDpSuffix( const wxString& aNetName, wxString& aComplementNet, wxString& aBaseDpName );
93 
94 private:
100 
101  std::map<std::pair<const PNS::ITEM*, const PNS::ITEM*>, int> m_clearanceCache;
102  std::map<std::pair<const PNS::ITEM*, const PNS::ITEM*>, int> m_holeClearanceCache;
103  std::map<std::pair<const PNS::ITEM*, const PNS::ITEM*>, int> m_holeToHoleClearanceCache;
104 };
105 
106 
108  PNS::ROUTER_IFACE* aRouterIface ) :
109  m_routerIface( aRouterIface ),
110  m_board( aBoard ),
111  m_dummyTrack( aBoard ),
112  m_dummyArc( aBoard ),
113  m_dummyVia( aBoard )
114 {
115 }
116 
117 
119 {
120 }
121 
122 
124 {
125  if( aItem->Kind() == PNS::ITEM::SOLID_T )
126  {
127  const PAD* pad = dynamic_cast<const PAD*>( aItem->Parent() );
128 
129  if( pad && pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
130  return pad->GetDrillSize().x / 2;
131  }
132  else if( aItem->Kind() == PNS::ITEM::VIA_T )
133  {
134  const ::VIA* via = dynamic_cast<const ::VIA*>( aItem->Parent() );
135 
136  if( via )
137  return via->GetDrillValue() / 2;
138  }
139 
140  return 0;
141 }
142 
143 
145 {
146  int net_p, net_n;
147 
148  if( !DpNetPair( aA, net_p, net_n ) )
149  return false;
150 
151  if( aA->Net() == net_p && aB->Net() == net_n )
152  return true;
153  if( aB->Net() == net_p && aA->Net() == net_n )
154  return true;
155 
156  return false;
157 }
158 
159 
160 bool isCopper( const PNS::ITEM* aItem )
161 {
162  BOARD_ITEM* parent = aItem->Parent();
163 
164  if( parent && parent->Type() == PCB_PAD_T )
165  {
166  PAD* pad = static_cast<PAD*>( parent );
167  return pad->IsOnCopperLayer() && pad->GetAttribute() != PAD_ATTRIB_NPTH;
168  }
169 
170  return true;
171 }
172 
173 
174 bool isEdge( const PNS::ITEM* aItem )
175 {
176  const BOARD_ITEM *parent = aItem->Parent();
177 
178  if( parent )
179  {
180  return parent->GetLayer() == Edge_Cuts || parent->GetLayer () == Margin;
181  }
182 
183  return false;
184 }
185 
186 
188  const PNS::ITEM* aItemA, const PNS::ITEM* aItemB,
189  int aLayer, PNS::CONSTRAINT* aConstraint )
190 {
191  std::shared_ptr<DRC_ENGINE> drcEngine = m_board->GetDesignSettings().m_DRCEngine;
192 
193  if( !drcEngine )
194  return false;
195 
196  DRC_CONSTRAINT_T hostType;
197 
198  switch ( aType )
199  {
203  case PNS::CONSTRAINT_TYPE::CT_LENGTH: hostType = LENGTH_CONSTRAINT; break;
209  default: return false; // should not happen
210  }
211 
212  BOARD_ITEM* parentA = aItemA ? aItemA->Parent() : nullptr;
213  BOARD_ITEM* parentB = aItemB ? aItemB->Parent() : nullptr;
214  DRC_CONSTRAINT hostConstraint;
215 
216  // A track being routed may not have a BOARD_ITEM associated yet.
217  if( aItemA && !parentA )
218  {
219  switch( aItemA->Kind() )
220  {
221  case PNS::ITEM::ARC_T: parentA = &m_dummyArc; break;
222  case PNS::ITEM::VIA_T: parentA = &m_dummyVia; break;
223  case PNS::ITEM::SEGMENT_T: parentA = &m_dummyTrack; break;
224  case PNS::ITEM::LINE_T: parentA = &m_dummyTrack; break;
225  default: break;
226  }
227 
228  if( parentA )
229  {
230  parentA->SetLayer( (PCB_LAYER_ID) aLayer );
231  static_cast<BOARD_CONNECTED_ITEM*>( parentA )->SetNetCode( aItemA->Net(), true );
232  }
233  }
234 
235  if( aItemB && !parentB )
236  {
237  switch( aItemB->Kind() )
238  {
239  case PNS::ITEM::ARC_T: parentB = &m_dummyArc; break;
240  case PNS::ITEM::VIA_T: parentB = &m_dummyVia; break;
241  case PNS::ITEM::SEGMENT_T: parentB = &m_dummyTrack; break;
242  case PNS::ITEM::LINE_T: parentB = &m_dummyTrack; break;
243  default: break;
244  }
245 
246  if( parentB )
247  {
248  parentB->SetLayer( (PCB_LAYER_ID) aLayer );
249  static_cast<BOARD_CONNECTED_ITEM*>( parentB )->SetNetCode( aItemB->Net(), true );
250  }
251  }
252 
253  if( parentA )
254  hostConstraint = drcEngine->EvalRules( hostType, parentA, parentB, (PCB_LAYER_ID) aLayer );
255 
256  if( hostConstraint.IsNull() )
257  return false;
258 
259  switch ( aType )
260  {
269  aConstraint->m_Value = hostConstraint.GetValue();
270  aConstraint->m_RuleName = hostConstraint.GetName();
271  aConstraint->m_Type = aType;
272  return true;
273 
274  default:
275  return false;
276  }
277 }
278 
279 
281 {
282  std::pair<const PNS::ITEM*, const PNS::ITEM*> key( aA, aB );
283  auto it = m_clearanceCache.find( key );
284 
285  if( it != m_clearanceCache.end() )
286  return it->second;
287 
288  PNS::CONSTRAINT constraint;
289  int rv = 0;
290  int layer;
291 
292  if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() )
293  layer = aA->Layer();
294  else
295  layer = aB->Layer();
296 
297  if( isCopper( aA ) && ( !aB || isCopper( aB ) ) )
298  {
299  if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_CLEARANCE, aA, aB, layer, &constraint ) )
300  rv = constraint.m_Value.Min();
301  }
302 
303  if( isEdge( aA ) || ( aB && isEdge( aB ) ) )
304  {
305  if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_EDGE_CLEARANCE, aA, aB, layer, &constraint ) )
306  {
307  if( constraint.m_Value.Min() > rv )
308  rv = constraint.m_Value.Min();
309  }
310  }
311 
312  m_clearanceCache[ key ] = rv;
313  return rv;
314 }
315 
316 
318 {
319  std::pair<const PNS::ITEM*, const PNS::ITEM*> key( aA, aB );
320  auto it = m_holeClearanceCache.find( key );
321 
322  if( it != m_holeClearanceCache.end() )
323  return it->second;
324 
325  PNS::CONSTRAINT constraint;
326  int rv = 0;
327  int layer;
328 
329  if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() )
330  layer = aA->Layer();
331  else
332  layer = aB->Layer();
333 
334  if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_HOLE_CLEARANCE, aA, aB, layer, &constraint ) )
335  rv = constraint.m_Value.Min();
336 
337  m_holeClearanceCache[ key ] = rv;
338  return rv;
339 }
340 
341 
343 {
344  std::pair<const PNS::ITEM*, const PNS::ITEM*> key( aA, aB );
345  auto it = m_holeToHoleClearanceCache.find( key );
346 
347  if( it != m_holeToHoleClearanceCache.end() )
348  return it->second;
349 
350  PNS::CONSTRAINT constraint;
351  int rv = 0;
352  int layer;
353 
354  if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() )
355  layer = aA->Layer();
356  else
357  layer = aB->Layer();
358 
359  if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_HOLE_TO_HOLE, aA, aB, layer, &constraint ) )
360  rv = constraint.m_Value.Min();
361 
362  m_holeToHoleClearanceCache[ key ] = rv;
363  return rv;
364 }
365 
366 
367 bool PNS_KICAD_IFACE_BASE::inheritTrackWidth( PNS::ITEM* aItem, int* aInheritedWidth )
368 {
369  VECTOR2I p;
370 
371  assert( aItem->Owner() != NULL );
372 
373  switch( aItem->Kind() )
374  {
375  case PNS::ITEM::VIA_T:
376  p = static_cast<PNS::VIA*>( aItem )->Pos();
377  break;
378 
379  case PNS::ITEM::SOLID_T:
380  p = static_cast<PNS::SOLID*>( aItem )->Pos();
381  break;
382 
384  *aInheritedWidth = static_cast<PNS::SEGMENT*>( aItem )->Width();
385  return true;
386 
387  default:
388  return false;
389  }
390 
391  PNS::JOINT* jt = static_cast<PNS::NODE*>( aItem->Owner() )->FindJoint( p, aItem );
392 
393  assert( jt != NULL );
394 
395  int mval = INT_MAX;
396 
397  PNS::ITEM_SET linkedSegs = jt->Links();
398  linkedSegs.ExcludeItem( aItem ).FilterKinds( PNS::ITEM::SEGMENT_T );
399 
400  for( PNS::ITEM* item : linkedSegs.Items() )
401  {
402  int w = static_cast<PNS::SEGMENT*>( item )->Width();
403  mval = std::min( w, mval );
404  }
405 
406  if( mval == INT_MAX )
407  return false;
408 
409  *aInheritedWidth = mval;
410  return true;
411 }
412 
413 
415 {
417  PNS::CONSTRAINT constraint;
418 
419  int trackWidth = bds.m_TrackMinWidth;
420  bool found = false;
421 
422  if( bds.m_UseConnectedTrackWidth && aStartItem != nullptr )
423  {
424  found = inheritTrackWidth( aStartItem, &trackWidth );
425  }
426 
427  if( !found && bds.UseNetClassTrack() && aStartItem )
428  {
430  aStartItem->Layer(), &constraint ) )
431  {
432  trackWidth = constraint.m_Value.Opt();
433  found = true; // Note: allowed to override anything, including bds.m_TrackMinWidth
434  }
435  }
436 
437  if( !found )
438  {
439  trackWidth = bds.GetCurrentTrackWidth();
440  }
441 
442  aSizes.SetTrackWidth( trackWidth );
443 
444  int viaDiameter = bds.m_ViasMinSize;
445  int viaDrill = bds.m_MinThroughDrill;
446 
447  if( bds.UseNetClassVia() && aStartItem ) // netclass value
448  {
450  nullptr, aStartItem->Layer(), &constraint ) )
451  {
452  viaDiameter = constraint.m_Value.Opt();
453  }
454 
456  nullptr, aStartItem->Layer(), &constraint ) )
457  {
458  viaDrill = constraint.m_Value.Opt();
459  }
460  }
461  else
462  {
463  viaDiameter = bds.GetCurrentViaSize();
464  viaDrill = bds.GetCurrentViaDrill();
465  }
466 
467  aSizes.SetViaDiameter( viaDiameter );
468  aSizes.SetViaDrill( viaDrill );
469 
470  int diffPairWidth = bds.m_TrackMinWidth;
471  int diffPairGap = bds.m_MinClearance;
472  int diffPairViaGap = bds.m_MinClearance;
473 
474  if( bds.UseNetClassDiffPair() && aStartItem )
475  {
477  nullptr, aStartItem->Layer(), &constraint ) )
478  {
479  diffPairWidth = constraint.m_Value.Opt();
480  }
481 
483  nullptr, aStartItem->Layer(), &constraint ) )
484  {
485  diffPairGap = constraint.m_Value.Opt();
486  diffPairViaGap = constraint.m_Value.Opt();
487  }
488  }
489  else
490  {
491  diffPairWidth = bds.GetCurrentDiffPairWidth();
492  diffPairGap = bds.GetCurrentDiffPairGap();
493  diffPairViaGap = bds.GetCurrentDiffPairViaGap();
494  }
495 
496  //printf( "DPWidth: %d gap %d\n", diffPairWidth, diffPairGap );
497 
498  aSizes.SetDiffPairWidth( diffPairWidth );
499  aSizes.SetDiffPairGap( diffPairGap );
500  aSizes.SetDiffPairViaGap( diffPairViaGap );
501 
502  int holeToHoleMin = bds.m_HoleToHoleMin;
503  PNS::VIA dummyVia;
504 
506  &dummyVia, UNDEFINED_LAYER, &constraint ) )
507  {
508  holeToHoleMin = constraint.m_Value.Min();
509  }
510 
511  aSizes.SetHoleToHole( holeToHoleMin );
512 
513  aSizes.ClearLayerPairs();
514 
515  return true;
516 }
517 
518 
519 int PNS_PCBNEW_RULE_RESOLVER::matchDpSuffix( const wxString& aNetName, wxString& aComplementNet,
520  wxString& aBaseDpName )
521 {
522  int rv = 0;
523 
524  if( aNetName.EndsWith( "+" ) )
525  {
526  aComplementNet = "-";
527  rv = 1;
528  }
529  else if( aNetName.EndsWith( "P" ) )
530  {
531  aComplementNet = "N";
532  rv = 1;
533  }
534  else if( aNetName.EndsWith( "-" ) )
535  {
536  aComplementNet = "+";
537  rv = -1;
538  }
539  else if( aNetName.EndsWith( "N" ) )
540  {
541  aComplementNet = "P";
542  rv = -1;
543  }
544  // Match P followed by 2 digits
545  else if( aNetName.Right( 2 ).IsNumber() && aNetName.Right( 3 ).Left( 1 ) == "P" )
546  {
547  aComplementNet = "N" + aNetName.Right( 2 );
548  rv = 1;
549  }
550  // Match P followed by 1 digit
551  else if( aNetName.Right( 1 ).IsNumber() && aNetName.Right( 2 ).Left( 1 ) == "P" )
552  {
553  aComplementNet = "N" + aNetName.Right( 1 );
554  rv = 1;
555  }
556  // Match N followed by 2 digits
557  else if( aNetName.Right( 2 ).IsNumber() && aNetName.Right( 3 ).Left( 1 ) == "N" )
558  {
559  aComplementNet = "P" + aNetName.Right( 2 );
560  rv = -1;
561  }
562  // Match N followed by 1 digit
563  else if( aNetName.Right( 1 ).IsNumber() && aNetName.Right( 2 ).Left( 1 ) == "N" )
564  {
565  aComplementNet = "P" + aNetName.Right( 1 );
566  rv = -1;
567  }
568  if( rv != 0 )
569  {
570  aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
571  aComplementNet = aBaseDpName + aComplementNet;
572  }
573 
574  return rv;
575 }
576 
577 
579 {
580  wxString refName = m_board->FindNet( aNet )->GetNetname();
581  wxString dummy, coupledNetName;
582 
583  if( matchDpSuffix( refName, coupledNetName, dummy ) )
584  {
585  NETINFO_ITEM* net = m_board->FindNet( coupledNetName );
586 
587  if( !net )
588  return -1;
589 
590  return net->GetNetCode();
591  }
592 
593  return -1;
594 }
595 
596 
598 {
599  return m_board->FindNet( aNet )->GetNetname();
600 }
601 
602 
604 {
605  wxString refName = m_board->FindNet( aNet )->GetNetname();
606  wxString dummy1, dummy2;
607 
608  return matchDpSuffix( refName, dummy1, dummy2 );
609 }
610 
611 
612 bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( const PNS::ITEM* aItem, int& aNetP, int& aNetN )
613 {
614  if( !aItem || !aItem->Parent() || !aItem->Parent()->IsConnected() )
615  return false;
616 
617  BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem->Parent() );
618  NETINFO_ITEM* netInfo = cItem->GetNet();
619 
620  if( !netInfo )
621  return false;
622 
623  wxString netNameP = netInfo->GetNetname();
624  wxString netNameN, netNameCoupled, netNameBase;
625 
626  int r = matchDpSuffix( netNameP, netNameCoupled, netNameBase );
627 
628  if( r == 0 )
629  {
630  return false;
631  }
632  else if( r == 1 )
633  {
634  netNameN = netNameCoupled;
635  }
636  else
637  {
638  netNameN = netNameP;
639  netNameP = netNameCoupled;
640  }
641 
642 // wxLogTrace( "PNS","p %s n %s base %s\n", (const char *)netNameP.c_str(), (const char *)netNameN.c_str(), (const char *)netNameBase.c_str() );
643 
644  NETINFO_ITEM* netInfoP = m_board->FindNet( netNameP );
645  NETINFO_ITEM* netInfoN = m_board->FindNet( netNameN );
646 
647  //wxLogTrace( "PNS","ip %p in %p\n", netInfoP, netInfoN);
648 
649  if( !netInfoP || !netInfoN )
650  return false;
651 
652  aNetP = netInfoP->GetNetCode();
653  aNetN = netInfoN->GetNetCode();
654 
655  return true;
656 }
657 
658 
660 {
661 public:
663  PNS::DEBUG_DECORATOR(),
664  m_view( NULL ),
665  m_items( NULL )
666  {
667  SetView( aView );
668  }
669 
671  {
672  Clear();
673  delete m_items;
674  }
675 
676  void SetView( KIGFX::VIEW* aView )
677  {
678  Clear();
679  delete m_items;
680  m_items = NULL;
681  m_view = aView;
682 
683  if( m_view == NULL )
684  return;
685 
688  m_view->Add( m_items );
689  }
690 
691  virtual void AddPoint( VECTOR2I aP, int aColor, int aSize, const std::string aName ) override
692  {
694 
695  l.Append( aP - VECTOR2I( -aSize, -aSize ) );
696  l.Append( aP + VECTOR2I( -aSize, -aSize ) );
697 
698  AddLine( l, aColor, 10000 );
699 
700  l.Clear();
701  l.Append( aP - VECTOR2I( aSize, -aSize ) );
702  l.Append( aP + VECTOR2I( aSize, -aSize ) );
703 
704  AddLine( l, aColor, 10000 );
705  }
706 
707  void AddBox( BOX2I aB, int aColor, const std::string aName = "" ) override
708  {
710 
711  VECTOR2I o = aB.GetOrigin();
712  VECTOR2I s = aB.GetSize();
713 
714  l.Append( o );
715  l.Append( o.x + s.x, o.y );
716  l.Append( o.x + s.x, o.y + s.y );
717  l.Append( o.x, o.y + s.y );
718  l.Append( o );
719 
720  AddLine( l, aColor, 10000 );
721  }
722 
723  void AddSegment( SEG aS, int aColor, const std::string aName = "" ) override
724  {
726 
727  l.Append( aS.A );
728  l.Append( aS.B );
729 
730  AddLine( l, aColor, 10000 );
731  }
732 
733  void AddDirections( VECTOR2D aP, int aMask, int aColor,
734  const std::string aName = "" ) override
735  {
736  BOX2I b( aP - VECTOR2I( 10000, 10000 ), VECTOR2I( 20000, 20000 ) );
737 
738  AddBox( b, aColor );
739  for( int i = 0; i < 8; i++ )
740  {
741  if( ( 1 << i ) & aMask )
742  {
743  VECTOR2I v = DIRECTION_45( ( DIRECTION_45::Directions ) i ).ToVector() * 100000;
744  AddSegment( SEG( aP, aP + v ), aColor );
745  }
746  }
747  }
748 
749  void AddLine( const SHAPE_LINE_CHAIN& aLine, int aType, int aWidth,
750  const std::string aName = "" ) override
751  {
752  if( !m_view )
753  return;
754 
756 
757  pitem->Line( aLine, aWidth, aType );
758  m_items->Add( pitem ); // Should not be needed, as m_items has been passed as a parent group in alloc;
759  m_view->Update( m_items );
760  }
761 
762  void Clear() override
763  {
764  if( m_view && m_items )
765  {
766  m_items->FreeItems();
767  m_view->Update( m_items );
768  }
769  }
770 
771 private:
774 };
775 
776 
778 {
779  return m_debugDecorator;
780 }
781 
782 
784 {
785  m_ruleResolver = nullptr;
786  m_board = nullptr;
787  m_world = nullptr;
788  m_debugDecorator = nullptr;
789 }
790 
791 
793 {
794  m_tool = nullptr;
795  m_view = nullptr;
796  m_previewItems = nullptr;
797  m_dispOptions = nullptr;
798 }
799 
800 
802 {
803 }
804 
805 
807 {
808  delete m_ruleResolver;
809  delete m_debugDecorator;
810 
811  if( m_previewItems )
812  {
814  delete m_previewItems;
815  }
816 }
817 
818 
819 std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( PAD* aPad )
820 {
821  LAYER_RANGE layers( 0, MAX_CU_LAYERS - 1 );
822 
823  // ignore non-copper pads except for those with holes
824  if( ( aPad->GetLayerSet() & LSET::AllCuMask() ).none() && aPad->GetDrillSize().x == 0 )
825  return NULL;
826 
827  switch( aPad->GetAttribute() )
828  {
829  case PAD_ATTRIB_PTH:
830  case PAD_ATTRIB_NPTH:
831  break;
832 
833  case PAD_ATTRIB_CONN:
834  case PAD_ATTRIB_SMD:
835  {
836  LSET lmsk = aPad->GetLayerSet();
837  bool is_copper = false;
838 
839  for( int i = 0; i < MAX_CU_LAYERS; i++ )
840  {
841  if( lmsk[i] )
842  {
843  is_copper = true;
844 
845  if( aPad->GetAttribute() != PAD_ATTRIB_NPTH )
846  layers = LAYER_RANGE( i );
847 
848  break;
849  }
850  }
851 
852  if( !is_copper )
853  return NULL;
854  }
855  break;
856 
857  default:
858  wxLogTrace( "PNS", "unsupported pad type 0x%x", aPad->GetAttribute() );
859  return NULL;
860  }
861 
862  std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
863 
864  if( aPad->GetDrillSize().x > 0 )
865  {
867 
868  if( aPad->GetAttribute() != PAD_ATTRIB_NPTH )
869  {
871  slot->SetWidth( slot->GetWidth() + bds.GetHolePlatingThickness() * 2 );
872  }
873 
874  solid->SetHole( slot );
875  }
876 
877  if( aPad->GetAttribute() == PAD_ATTRIB_NPTH )
878  solid->SetRoutable( false );
879 
880  solid->SetLayers( layers );
881  solid->SetNet( aPad->GetNetCode() );
882  solid->SetParent( aPad );
883  solid->SetPadToDie( aPad->GetPadToDieLength() );
884  solid->SetOrientation( aPad->GetOrientation() );
885 
886  wxPoint wx_c = aPad->ShapePos();
887  wxPoint offset = aPad->GetOffset();
888 
889  VECTOR2I c( wx_c.x, wx_c.y );
890 
891  RotatePoint( &offset, aPad->GetOrientation() );
892 
893  solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) );
894  solid->SetOffset( VECTOR2I( offset.x, offset.y ) );
895 
896 
897  auto shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
898 
899  if( shapes && shapes->Size() == 1 )
900  {
901  solid->SetShape( shapes->Shapes()[0]->Clone() );
902  }
903  else
904  {
905  // Fixme (but not urgent). For complex pad shapes, we pass a single simple polygon to the
906  // router, otherwise it won't know how to correctly build walkaround 'hulls' for the pad
907  // primitives - it can recognize only simple shapes, but not COMPOUNDs made of multiple shapes.
908  // The proper way to fix this would be to implement SHAPE_COMPOUND::ConvertToSimplePolygon(),
909  // but the complexity of pad polygonization code (see PAD::GetEffectivePolygon), including approximation
910  // error handling makes me slightly scared to do it right now.
911 
912  const std::shared_ptr<SHAPE_POLY_SET>& outline = aPad->GetEffectivePolygon();
913  SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
914 
915  for( auto iter = outline->CIterate( 0 ); iter; iter++ )
916  shape->Append( *iter );
917 
918  solid->SetShape( shape );
919  }
920 
921  return solid;
922 }
923 
924 
925 std::unique_ptr<PNS::SEGMENT> PNS_KICAD_IFACE_BASE::syncTrack( TRACK* aTrack )
926 {
927  auto segment = std::make_unique<PNS::SEGMENT>( SEG( aTrack->GetStart(), aTrack->GetEnd() ),
928  aTrack->GetNetCode() );
929 
930  segment->SetWidth( aTrack->GetWidth() );
931  segment->SetLayers( LAYER_RANGE( aTrack->GetLayer() ) );
932  segment->SetParent( aTrack );
933 
934  if( aTrack->IsLocked() )
935  segment->Mark( PNS::MK_LOCKED );
936 
937  return segment;
938 }
939 
940 
941 std::unique_ptr<PNS::ARC> PNS_KICAD_IFACE_BASE::syncArc( ARC* aArc )
942 {
943  auto arc = std::make_unique<PNS::ARC>( SHAPE_ARC( aArc->GetStart(), aArc->GetMid(), aArc->GetEnd(),
944  aArc->GetWidth() ),
945  aArc->GetNetCode() );
946 
947  arc->SetLayers( LAYER_RANGE( aArc->GetLayer() ) );
948  arc->SetParent( aArc );
949 
950  if( aArc->IsLocked() )
951  arc->Mark( PNS::MK_LOCKED );
952 
953  return arc;
954 }
955 
956 
957 std::unique_ptr<PNS::VIA> PNS_KICAD_IFACE_BASE::syncVia( VIA* aVia )
958 {
959  PCB_LAYER_ID top, bottom;
960  aVia->LayerPair( &top, &bottom );
961 
962  auto via = std::make_unique<PNS::VIA>( aVia->GetPosition(),
963  LAYER_RANGE( aVia->TopLayer(), aVia->BottomLayer() ),
964  aVia->GetWidth(),
965  aVia->GetDrillValue(),
966  aVia->GetNetCode(),
967  aVia->GetViaType() );
968 
969  via->SetParent( aVia );
970 
971  if( aVia->IsLocked() )
972  via->Mark( PNS::MK_LOCKED );
973 
974  via->SetIsFree( aVia->GetIsFree() );
975 
977  via->SetHole( SHAPE_CIRCLE( aVia->GetPosition(),
978  aVia->GetDrill() / 2 + bds.GetHolePlatingThickness() ) );
979 
980  return via;
981 }
982 
983 
984 bool PNS_KICAD_IFACE_BASE::syncZone( PNS::NODE* aWorld, ZONE* aZone, SHAPE_POLY_SET* aBoardOutline )
985 {
986  SHAPE_POLY_SET* poly;
987 
988  if( !aZone->GetIsRuleArea() && aZone->GetZoneName().IsEmpty() )
989  return false;
990 
991  // Required by expression function insideArea()
992  aZone->CacheBoundingBox();
993 
994  // TODO handle aZone->GetDoNotAllowVias()
995  // TODO handle rules which disallow tracks & vias
996  if( !aZone->GetIsRuleArea() || !aZone->GetDoNotAllowTracks() )
997  return false;
998 
999  LSET layers = aZone->GetLayerSet();
1000  EDA_UNITS units = EDA_UNITS::MILLIMETRES; // TODO: get real units
1001 
1002  poly = aZone->Outline();
1003  poly->CacheTriangulation( false );
1004 
1005  if( !poly->IsTriangulationUpToDate() )
1006  {
1007  KIDIALOG dlg( nullptr, wxString::Format( _( "%s is malformed." ),
1008  aZone->GetSelectMenuText( units ) ),
1010  dlg.ShowDetailedText( wxString::Format( _( "This zone cannot be handled by the track "
1011  "layout tool.\n"
1012  "Please verify it is not a "
1013  "self-intersecting polygon." ) ) );
1014  dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
1015  dlg.ShowModal();
1016 
1017  return false;
1018  }
1019 
1020  for( int layer = F_Cu; layer <= B_Cu; layer++ )
1021  {
1022  if( !layers[ layer ] )
1023  continue;
1024 
1025  for( int outline = 0; outline < poly->OutlineCount(); outline++ )
1026  {
1027  const SHAPE_POLY_SET::TRIANGULATED_POLYGON* tri = poly->TriangulatedPolygon( outline );
1028 
1029  for( size_t i = 0; i < tri->GetTriangleCount(); i++)
1030  {
1031  VECTOR2I a, b, c;
1032  tri->GetTriangle( i, a, b, c );
1033  SHAPE_SIMPLE* triShape = new SHAPE_SIMPLE;
1034 
1035  triShape->Append( a );
1036  triShape->Append( b );
1037  triShape->Append( c );
1038 
1039  std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
1040 
1041  solid->SetLayer( layer );
1042  solid->SetNet( -1 );
1043  solid->SetParent( aZone );
1044  solid->SetShape( triShape );
1045  solid->SetRoutable( false );
1046 
1047  aWorld->Add( std::move( solid ) );
1048  }
1049  }
1050  }
1051 
1052  return true;
1053 }
1054 
1055 
1057 {
1058  if( !IsCopperLayer( aLayer ) )
1059  return false;
1060 
1061  int textWidth = aText->GetEffectiveTextPenWidth();
1062  std::vector<wxPoint> textShape = aText->TransformToSegmentList();
1063 
1064  if( textShape.size() < 2 )
1065  return false;
1066 
1067  for( size_t jj = 0; jj < textShape.size(); jj += 2 )
1068  {
1069  VECTOR2I start( textShape[jj] );
1070  VECTOR2I end( textShape[jj+1] );
1071  std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
1072 
1073  solid->SetLayer( aLayer );
1074  solid->SetNet( -1 );
1075  solid->SetParent( dynamic_cast<BOARD_ITEM*>( aText ) );
1076  solid->SetShape( new SHAPE_SEGMENT( start, end, textWidth ) );
1077  solid->SetRoutable( false );
1078 
1079  aWorld->Add( std::move( solid ) );
1080  }
1081 
1082  return true;
1083 
1084  /* A coarser (but faster) method:
1085  *
1086  SHAPE_POLY_SET outline;
1087  SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
1088 
1089  aText->TransformBoundingBoxWithClearanceToPolygon( &outline, 0 );
1090 
1091  for( auto iter = outline.CIterate( 0 ); iter; iter++ )
1092  shape->Append( *iter );
1093 
1094  solid->SetShape( shape );
1095 
1096  solid->SetLayer( aLayer );
1097  solid->SetNet( -1 );
1098  solid->SetParent( nullptr );
1099  solid->SetRoutable( false );
1100  aWorld->Add( std::move( solid ) );
1101  return true;
1102  */
1103 }
1104 
1105 
1107 {
1108  if( aItem->GetLayer() == Edge_Cuts
1109  || aItem->GetLayer() == Margin
1110  || IsCopperLayer( aItem->GetLayer() ) )
1111  {
1112  // TODO: where do we handle filled polygons on copper layers?
1113  if( aItem->GetShape() == S_POLYGON && aItem->IsFilled() )
1114  return false;
1115 
1116  for( SHAPE* shape : aItem->MakeEffectiveShapes() )
1117  {
1118  std::unique_ptr<PNS::SOLID> solid = std::make_unique<PNS::SOLID>();
1119 
1120  if( aItem->GetLayer() == Edge_Cuts || aItem->GetLayer() == Margin )
1121  solid->SetLayers( LAYER_RANGE( F_Cu, B_Cu ) );
1122  else
1123  solid->SetLayer( aItem->GetLayer() );
1124 
1125  if( aItem->GetLayer() == Edge_Cuts )
1126  {
1127  switch( shape->Type() )
1128  {
1129  case SH_SEGMENT: static_cast<SHAPE_SEGMENT*>( shape )->SetWidth( 0 ); break;
1130  case SH_ARC: static_cast<SHAPE_ARC*>( shape )->SetWidth( 0 ); break;
1131  case SH_LINE_CHAIN: static_cast<SHAPE_LINE_CHAIN*>( shape )->SetWidth( 0 ); break;
1132  default: /* remaining shapes don't have width */ break;
1133  }
1134  }
1135 
1136  solid->SetNet( -1 );
1137  solid->SetParent( aItem );
1138  solid->SetShape( shape );
1139  solid->SetRoutable( false );
1140 
1141  aWorld->Add( std::move( solid ) );
1142  }
1143 
1144  return true;
1145  }
1146 
1147  return false;
1148 }
1149 
1150 
1152 {
1153  m_board = aBoard;
1154  wxLogTrace( "PNS", "m_board = %p", m_board );
1155 }
1156 
1157 
1159 {
1160  if( !m_view )
1161  return false;
1162 
1163  for( int i = aLayer.Start(); i <= aLayer.End(); i++ )
1164  if( m_view->IsLayerVisible( i ) )
1165  return true;
1166 
1167  return false;
1168 }
1169 
1170 
1171 bool PNS_KICAD_IFACE::IsFlashedOnLayer( const PNS::ITEM* aItem, int aLayer ) const
1172 {
1174  if( aLayer < 0 )
1175  return true;
1176 
1177  if( aItem->Parent() )
1178  {
1179  switch( aItem->Parent()->Type() )
1180  {
1181  case PCB_VIA_T:
1182  {
1183  const VIA* via = static_cast<const VIA*>( aItem->Parent() );
1184 
1185  return via->FlashLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
1186  }
1187 
1188  case PCB_PAD_T:
1189  {
1190  const PAD* pad = static_cast<const PAD*>( aItem->Parent() );
1191 
1192  return pad->FlashLayer( static_cast<PCB_LAYER_ID>( aLayer ) );
1193  }
1194 
1195  default:
1196  break;
1197  }
1198  }
1199 
1200  return aItem->Layers().Overlaps( aLayer );
1201 }
1202 
1203 
1204 bool PNS_KICAD_IFACE::IsItemVisible( const PNS::ITEM* aItem ) const
1205 {
1206  // by default, all items are visible (new ones created by the router have parent == NULL
1207  // as they have not been committed yet to the BOARD)
1208  if( !m_view || !aItem->Parent() )
1209  return true;
1210 
1211  BOARD_ITEM* item = aItem->Parent();
1212  bool isOnVisibleLayer = true;
1213  RENDER_SETTINGS* settings = m_view->GetPainter()->GetSettings();
1214 
1215  if( settings->GetHighContrast() )
1216  isOnVisibleLayer = item->IsOnLayer( settings->GetPrimaryHighContrastLayer() );
1217 
1218  if( m_view->IsVisible( item ) && isOnVisibleLayer
1219  && item->ViewGetLOD( item->GetLayer(), m_view ) < m_view->GetScale() )
1220  {
1221  return true;
1222  }
1223 
1224  // Items hidden in the router are not hidden on the board
1225  if( m_hiddenItems.find( item ) != m_hiddenItems.end() )
1226  return true;
1227 
1228  return false;
1229 }
1230 
1231 
1233 {
1234  if( !m_board )
1235  {
1236  wxLogTrace( "PNS", "No board attached, aborting sync." );
1237  return;
1238  }
1239 
1240  int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
1241 
1242  m_world = aWorld;
1243 
1244  for( BOARD_ITEM* gitem : m_board->Drawings() )
1245  {
1246  if ( gitem->Type() == PCB_SHAPE_T )
1247  {
1248  syncGraphicalItem( aWorld, static_cast<PCB_SHAPE*>( gitem ) );
1249  }
1250  else if( gitem->Type() == PCB_TEXT_T )
1251  {
1252  syncTextItem( aWorld, static_cast<PCB_TEXT*>( gitem ), gitem->GetLayer() );
1253  }
1254  }
1255 
1256  SHAPE_POLY_SET buffer;
1257  SHAPE_POLY_SET* boardOutline = nullptr;
1258 
1259  if( m_board->GetBoardPolygonOutlines( buffer ) )
1260  boardOutline = &buffer;
1261 
1262  for( ZONE* zone : m_board->Zones() )
1263  {
1264  syncZone( aWorld, zone, boardOutline );
1265  }
1266 
1267  for( FOOTPRINT* footprint : m_board->Footprints() )
1268  {
1269  for( PAD* pad : footprint->Pads() )
1270  {
1271  if( std::unique_ptr<PNS::SOLID> solid = syncPad( pad ) )
1272  aWorld->Add( std::move( solid ) );
1273 
1274  worstClearance = std::max( worstClearance, pad->GetLocalClearance() );
1275  }
1276 
1277  syncTextItem( aWorld, &footprint->Reference(), footprint->Reference().GetLayer() );
1278  syncTextItem( aWorld, &footprint->Value(), footprint->Value().GetLayer() );
1279 
1280  for( FP_ZONE* zone : footprint->Zones() )
1281  syncZone( aWorld, zone, boardOutline );
1282 
1283  if( footprint->IsNetTie() )
1284  continue;
1285 
1286  for( BOARD_ITEM* mgitem : footprint->GraphicalItems() )
1287  {
1288  if( mgitem->Type() == PCB_FP_SHAPE_T )
1289  {
1290  syncGraphicalItem( aWorld, static_cast<PCB_SHAPE*>( mgitem ) );
1291  }
1292  else if( mgitem->Type() == PCB_FP_TEXT_T )
1293  {
1294  syncTextItem( aWorld, static_cast<FP_TEXT*>( mgitem ), mgitem->GetLayer() );
1295  }
1296  }
1297  }
1298 
1299  for( TRACK* t : m_board->Tracks() )
1300  {
1301  KICAD_T type = t->Type();
1302 
1303  if( type == PCB_TRACE_T )
1304  {
1305  if( auto segment = syncTrack( t ) )
1306  aWorld->Add( std::move( segment ) );
1307  }
1308  else if( type == PCB_ARC_T )
1309  {
1310  if( auto arc = syncArc( static_cast<ARC*>( t ) ) )
1311  aWorld->Add( std::move( arc ) );
1312  }
1313  else if( type == PCB_VIA_T )
1314  {
1315  if( auto via = syncVia( static_cast<VIA*>( t ) ) )
1316  aWorld->Add( std::move( via ) );
1317  }
1318  }
1319 
1320  // NB: if this were ever to become a long-lived object we would need to dirty its
1321  // clearance cache here....
1322  delete m_ruleResolver;
1324 
1325  aWorld->SetRuleResolver( m_ruleResolver );
1326  aWorld->SetMaxClearance( 4 * worstClearance );
1327 }
1328 
1329 
1331 {
1332  for( auto item : m_hiddenItems )
1333  m_view->SetVisible( item, true );
1334 
1335  m_hiddenItems.clear();
1336 
1337  if( m_previewItems )
1338  {
1341  }
1342 
1343  if( m_debugDecorator )
1345 }
1346 
1348 {
1349  m_debugDecorator = aDec;
1350 }
1351 
1352 void PNS_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool aEdit )
1353 {
1354  ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_view );
1355 
1356  if( aClearance >= 0 )
1357  {
1358  pitem->SetClearance( aClearance );
1359 
1361  {
1363  pitem->ShowTrackClearance( false );
1364  pitem->ShowViaClearance( false );
1365  break;
1368  pitem->ShowTrackClearance( true );
1369  pitem->ShowViaClearance( true );
1370  break;
1371 
1373  pitem->ShowTrackClearance( !aEdit );
1374  pitem->ShowViaClearance( !aEdit );
1375  break;
1376 
1378  pitem->ShowTrackClearance( !aEdit );
1379  pitem->ShowViaClearance( false );
1380  break;
1381  }
1382  }
1383 
1384 
1385  m_previewItems->Add( pitem );
1387 }
1388 
1389 
1390 void PNS_KICAD_IFACE::DisplayRatline( const SHAPE_LINE_CHAIN& aRatline, int aColor )
1391 {
1392  ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( nullptr, m_view );
1393  pitem->Line( aRatline, 10000, aColor );
1394  m_previewItems->Add( pitem );
1396 }
1397 
1398 
1400 {
1401  BOARD_ITEM* parent = aItem->Parent();
1402 
1403  if( parent )
1404  {
1405  if( m_view->IsVisible( parent ) )
1406  m_hiddenItems.insert( parent );
1407 
1408  m_view->SetVisible( parent, false );
1409  m_view->Update( parent, KIGFX::APPEARANCE );
1410  }
1411 }
1412 
1413 
1415 {
1416 
1417 }
1418 
1419 
1421 {
1422  BOARD_ITEM* parent = aItem->Parent();
1423 
1424  if( aItem->OfKind( PNS::ITEM::SOLID_T ) )
1425  {
1426  PAD* pad = static_cast<PAD*>( parent );
1427  VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
1428 
1429  m_fpOffsets[ pad ].p_old = pos;
1430  return;
1431  }
1432 
1433  if( parent )
1434  {
1435  m_commit->Remove( parent );
1436  }
1437 }
1438 
1439 
1441 {
1442 
1443 }
1444 
1445 
1447 {
1448  BOARD_ITEM* board_item = aItem->Parent();
1449 
1450  m_commit->Modify( board_item );
1451 
1452  switch( aItem->Kind() )
1453  {
1454  case PNS::ITEM::ARC_T:
1455  {
1456  PNS::ARC* arc = static_cast<PNS::ARC*>( aItem );
1457  ARC* arc_board = static_cast<ARC*>( board_item );
1458  const SHAPE_ARC* arc_shape = static_cast<const SHAPE_ARC*>( arc->Shape() );
1459  arc_board->SetStart( wxPoint( arc_shape->GetP0() ) );
1460  arc_board->SetEnd( wxPoint( arc_shape->GetP1() ) );
1461  arc_board->SetMid( wxPoint( arc_shape->GetArcMid() ) );
1462  arc_board->SetWidth( arc->Width() );
1463  break;
1464  }
1465 
1466  case PNS::ITEM::SEGMENT_T:
1467  {
1468  PNS::SEGMENT* seg = static_cast<PNS::SEGMENT*>( aItem );
1469  TRACK* track = static_cast<TRACK*>( board_item );
1470  const SEG& s = seg->Seg();
1471  track->SetStart( wxPoint( s.A.x, s.A.y ) );
1472  track->SetEnd( wxPoint( s.B.x, s.B.y ) );
1473  track->SetWidth( seg->Width() );
1474  break;
1475  }
1476 
1477  case PNS::ITEM::VIA_T:
1478  {
1479  VIA* via_board = static_cast<VIA*>( board_item );
1480  PNS::VIA* via = static_cast<PNS::VIA*>( aItem );
1481  via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) );
1482  via_board->SetWidth( via->Diameter() );
1483  via_board->SetDrill( via->Drill() );
1484  via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 );
1485  via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
1486  via_board->SetIsFree( via->IsFree() );
1487  via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
1488  ToLAYER_ID( via->Layers().End() ) );
1489  break;
1490  }
1491 
1492  case PNS::ITEM::SOLID_T:
1493  {
1494  PAD* pad = static_cast<PAD*>( aItem->Parent() );
1495  VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
1496 
1497  m_fpOffsets[ pad ].p_old = pad->GetPosition();
1498  m_fpOffsets[ pad ].p_new = pos;
1499  break;
1500  }
1501 
1502  default:
1503  break;
1504  }
1505 }
1506 
1507 
1509 {
1510 
1511 }
1512 
1513 
1515 {
1516  BOARD_CONNECTED_ITEM* newBI = NULL;
1517 
1518  switch( aItem->Kind() )
1519  {
1520  case PNS::ITEM::ARC_T:
1521  {
1522  auto arc = static_cast<PNS::ARC*>( aItem );
1523  ARC* new_arc = new ARC( m_board, static_cast<const SHAPE_ARC*>( arc->Shape() ) );
1524  new_arc->SetWidth( arc->Width() );
1525  new_arc->SetLayer( ToLAYER_ID( arc->Layers().Start() ) );
1526  new_arc->SetNetCode( std::max<int>( 0, arc->Net() ) );
1527  newBI = new_arc;
1528  break;
1529  }
1530 
1531  case PNS::ITEM::SEGMENT_T:
1532  {
1533  PNS::SEGMENT* seg = static_cast<PNS::SEGMENT*>( aItem );
1534  TRACK* track = new TRACK( m_board );
1535  const SEG& s = seg->Seg();
1536  track->SetStart( wxPoint( s.A.x, s.A.y ) );
1537  track->SetEnd( wxPoint( s.B.x, s.B.y ) );
1538  track->SetWidth( seg->Width() );
1539  track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) );
1540  track->SetNetCode( seg->Net() > 0 ? seg->Net() : 0 );
1541  newBI = track;
1542  break;
1543  }
1544 
1545  case PNS::ITEM::VIA_T:
1546  {
1547  VIA* via_board = new VIA( m_board );
1548  PNS::VIA* via = static_cast<PNS::VIA*>( aItem );
1549  via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) );
1550  via_board->SetWidth( via->Diameter() );
1551  via_board->SetDrill( via->Drill() );
1552  via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 );
1553  via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
1554  via_board->SetIsFree( via->IsFree() );
1555  via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
1556  ToLAYER_ID( via->Layers().End() ) );
1557  newBI = via_board;
1558  break;
1559  }
1560 
1561  case PNS::ITEM::SOLID_T:
1562  {
1563  PAD* pad = static_cast<PAD*>( aItem->Parent() );
1564  VECTOR2I pos = static_cast<PNS::SOLID*>( aItem )->Pos();
1565 
1566  m_fpOffsets[ pad ].p_new = pos;
1567  return;
1568  }
1569 
1570  default:
1571  break;
1572  }
1573 
1574  if( newBI )
1575  {
1576  //newBI->SetLocalRatsnestVisible( m_dispOptions->m_ShowGlobalRatsnest );
1577  aItem->SetParent( newBI );
1578  newBI->ClearFlags();
1579 
1580  m_commit->Add( newBI );
1581  }
1582 }
1583 
1584 
1586 {
1587  std::set<FOOTPRINT*> processedMods;
1588 
1589  EraseView();
1590 
1591  for( auto fpOffset : m_fpOffsets )
1592  {
1593  VECTOR2I offset = fpOffset.second.p_new - fpOffset.second.p_old;
1594  FOOTPRINT* footprint = fpOffset.first->GetParent();
1595 
1596  VECTOR2I p_orig = footprint->GetPosition();
1597  VECTOR2I p_new = p_orig + offset;
1598 
1599  if( processedMods.find( footprint ) != processedMods.end() )
1600  continue;
1601 
1602  processedMods.insert( footprint );
1603  m_commit->Modify( footprint );
1604  footprint->SetPosition( wxPoint( p_new.x, p_new.y ) );
1605  }
1606 
1607  m_fpOffsets.clear();
1608 
1609  m_commit->Push( _( "Interactive Router" ) );
1610  m_commit = std::make_unique<BOARD_COMMIT>( m_tool );
1611 }
1612 
1613 
1615 {
1616  wxLogTrace( "PNS", "SetView %p", aView );
1617 
1618  if( m_previewItems )
1619  {
1621  delete m_previewItems;
1622  }
1623 
1624  m_view = aView;
1627 
1628  if(m_view)
1630 
1631  delete m_debugDecorator;
1632 
1633  auto dec = new PNS_PCBNEW_DEBUG_DECORATOR();
1634  m_debugDecorator = dec;
1635 
1636  if( ADVANCED_CFG::GetCfg().m_ShowRouterDebugGraphics )
1637  dec->SetView( m_view );
1638 }
1639 
1640 
1641 void PNS_KICAD_IFACE::UpdateNet( int aNetCode )
1642 {
1643  wxLogTrace( "PNS", "Update-net %d", aNetCode );
1644 
1645 }
1646 
1648 {
1649  return m_ruleResolver;
1650 }
1651 
1652 
1654 {
1655  m_tool = aTool;
1656  m_commit = std::make_unique<BOARD_COMMIT>( m_tool );
1657 }
1658 
1660 {
1661  m_dispOptions = aDispOptions;
1662 }
Directions
Available directions, there are 8 of them, as on a rectilinear map (north = up) + an extra undefined ...
Definition: direction45.h:48
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)
std::unique_ptr< PNS::VIA > syncVia(VIA *aVia)
Base class for PNS router board items.
Definition: pns_item.h:55
void DisplayRatline(const SHAPE_LINE_CHAIN &aRatline, int aColor=-1) override
void AddSegment(SEG aS, int aColor, const std::string aName="") 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:1268
void AddDirections(VECTOR2D aP, int aMask, int aColor, const std::string aName="") override
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
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: track.cpp:435
Definition: track.h:343
bool IsFilled() const
Definition: pcb_shape.h:96
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:154
int OutlineCount() const
Return the number of vertices in a given outline/hole.
PNS::RULE_RESOLVER * GetRuleResolver() override
Keep the router "world" - i.e.
Definition: pns_node.h:149
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:1862
ZONES & Zones()
Definition: board.h:309
bool syncGraphicalItem(PNS::NODE *aWorld, PCB_SHAPE *aItem)
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
void SetPosition(const wxPoint &aPoint) override
Definition: track.h:412
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:755
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:194
This file is part of the common library.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
void SetEnd(const wxPoint &aEnd)
Definition: track.h:112
void GetTriangle(int index, VECTOR2I &a, VECTOR2I &b, VECTOR2I &c) const
bool IsMultilayer() const
Definition: pns_layerset.h:77
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
const wxPoint & GetStart() const
Definition: track.h:116
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:584
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:88
VIATYPE ViaType() const
Definition: pns_via.h:104
PNS::DEBUG_DECORATOR * m_debugDecorator
int GetHolePlatingThickness() const
Pad & via drills are finish size.
const VECTOR2I ToVector() const
Definition: direction45.h:274
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:323
ENTRIES & Items()
Definition: pns_itemset.h:138
void UpdateNet(int aNetCode) override
ITEM_SET & FilterKinds(int aKindMask, bool aInvert=false)
Definition: pns_itemset.cpp:68
void SetParent(BOARD_ITEM *aParent)
Definition: pns_item.h:144
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:81
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:54
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.cpp:288
bool GetIsFree() const
Checks if the via is a free via (as opposed to one created on a track by the router).
Definition: track.h:502
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 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
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Return a SHAPE object representing the pad's hole.
Definition: pcbnew/pad.cpp:286
T Opt() const
Definition: minoptmax.h:35
std::map< std::pair< const PNS::ITEM *, const PNS::ITEM * >, int > m_holeToHoleClearanceCache
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:591
wxString m_RuleName
Definition: pns_node.h:76
BOARD_ITEM * Parent() const
Definition: pns_item.h:145
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
PNS_PCBNEW_DEBUG_DECORATOR(KIGFX::VIEW *aView=NULL)
void Line(const SHAPE_LINE_CHAIN &aLine, int aWidth=0, int aStyle=0)
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:228
like PAD_PTH, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:85
void SetRuleResolver(RULE_RESOLVER *aFunc)
Definition: pns_node.h:177
void HideItem(PNS::ITEM *aItem) override
void AddBox(BOX2I aB, int aColor, const std::string aName="") override
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
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,...
const VECTOR2I & Pos() const
Definition: pns_via.h:96
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:127
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 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:157
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.
void SetWidth(int aWidth)
Definition: track.h:109
PAD_ATTR_T GetAttribute() const
Definition: pad.h:363
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:171
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:119
DRC_CONSTRAINT_T
Definition: drc_rule.h:41
ITEM_SET & Links()
Definition: pns_joint.h:205
const wxPoint & GetOffset() const
Definition: pad.h:249
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:242
wxPoint ShapePos() const
Definition: pcbnew/pad.cpp:657
Container for display options like enable/disable some optional drawings.
PCB_LAYER_ID
A quick note on layer IDs:
int Diameter() const
Definition: pns_via.h:107
void SetDiffPairViaGap(int aGap)
void FreeItems()
Free all the items that were added to the group.
Definition: view_group.cpp:198
bool FlashLayer(int aLayer) const
Check to see whether the pad should be flashed on the specific layer.
Definition: pcbnew/pad.cpp:202
LSET is a set of PCB_LAYER_IDs.
VIEW_ITEM class definition.
const wxPoint & GetMid() const
Definition: track.h:292
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
Definition: board_item.h:231
virtual bool DpNetPair(const PNS::ITEM *aItem, int &aNetP, int &aNetN) override
Normal via.
Definition: router_tool.cpp:67
#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:341
bool isEdge(const PNS::ITEM *aItem)
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Definition: track.cpp:173
bool IsVisible(const VIEW_ITEM *aItem) const
Return information if the item is visible (or not).
Definition: view.cpp:1494
Represent a set of closed polygons.
bool FlashLayer(int aLayer) const
Checks to see whether the via should have a pad on the specific layer.
Definition: track.cpp:494
std::unique_ptr< BOARD_COMMIT > m_commit
int Net() const
Definition: pns_item.h:148
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
bool IsItemVisible(const PNS::ITEM *aItem) const override
int GetDrill() const
Function GetDrill returns the local drill setting for this VIA.
Definition: track.h:481
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:303
virtual int DpCoupledNet(int aNet) override
PNS::DEBUG_DECORATOR * GetDebugDecorator() override
bool GetDoNotAllowTracks() const
Definition: zone.h:758
void ShowViaClearance(bool aEnabled)
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
Extend VIEW_ITEM by possibility of grouping items into a single object.
Definition: view_group.h:46
circular arc
Definition: shape.h:50
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: pcbnew/pad.cpp:277
KIGFX::VIEW_GROUP * m_previewItems
void UpdateItem(PNS::ITEM *aItem) override
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: track.cpp:414
ZONE handles 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:360
An abstract shape on 2D plane.
Definition: shape.h:116
void SyncWorld(PNS::NODE *aWorld) override
virtual void Add(VIEW_ITEM *aItem)
Add an item to the group.
Definition: view_group.cpp:56
bool IsOnCopperLayer() const override
Definition: pad.h:217
void SetMid(const wxPoint &aMid)
Definition: track.h:291
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:82
virtual void SetLayer(int aLayer)
Set layer used to draw the group.
Definition: view_group.h:108
void AddItem(PNS::ITEM *aItem) override
const PCB_DISPLAY_OPTIONS * m_dispOptions
void Commit() override
bool IsNull() const
Definition: drc_rule.h:116
void SetBoard(BOARD *aBoard)
virtual void AddPoint(VECTOR2I aP, int aColor, int aSize, const std::string aName) override
void EraseView() override
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
Definition: seg.h:41
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:78
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
Makes a set of SHAPE objects representing the PCB_SHAPE.
Definition: pcb_shape.cpp:1085
std::unique_ptr< PNS::ARC > syncArc(ARC *aArc)
KIGFX::VIEW * m_view
Handle the data for a net.
Definition: netinfo.h:64
virtual bool IsLocked() const
Definition: board_item.h:249
int GetWidth() const
Definition: track.h:110
Board layer functions and definitions.
const MINOPTMAX< int > & GetValue() const
Definition: drc_rule.h:121
void CacheBoundingBox()
Definition: zone.h:149
void SetHoleToHole(int aHoleToHole)
wxPoint GetPosition() const override
Definition: pad.h:177
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: pad.h:346
Definition: track.h:262
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)
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
void RemoveItem(PNS::ITEM *aItem) override
virtual wxString NetName(int aNet) override
VECTOR2I A
Definition: seg.h:49
bool OfKind(int aKindMask) const
Return true if the item's type matches the mask aKindMask.
Definition: pns_item.h:134
Plated through hole pad.
Definition: pad_shapes.h:80
void AddItem(PNS::ITEM *aItem) override
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: track.h:474
void SetIsFree(bool aFree=true)
Definition: track.h:503
void SetView(KIGFX::VIEW *aView)
int matchDpSuffix(const wxString &aNetName, wxString &aComplementNet, wxString &aBaseDpName)
VIATYPE GetViaType() const
Definition: track.h:373
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
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon() const
Definition: pcbnew/pad.cpp:268
line chain (polyline)
Definition: shape.h:45
PCB_TOOL_BASE * m_tool
wxPoint GetPosition() const override
Definition: footprint.h:182
PCB_LAYER_ID TopLayer() const
Definition: track.cpp:457
VECTOR2I::extended_type ecoord
const wxPoint & GetEnd() const
Definition: track.h:113
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:126
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: eda_item.h:203
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1454
void Clear()
Function Clear() Removes all points from the line chain.
void SetStart(const wxPoint &aStart)
Definition: track.h:115
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:136
void CacheTriangulation(bool aPartition=true)
class 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:321
const Vec & GetSize() const
Definition: box2.h:189
MINOPTMAX< int > m_Value
Definition: pns_node.h:74
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:130
PNS_PCBNEW_RULE_RESOLVER * m_ruleResolver
const Vec & GetOrigin() const
Definition: box2.h:193
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:167
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:852
Definition: pad.h:60
void SetPosition(const wxPoint &aPos) override
Definition: footprint.cpp:1437
wxPoint GetPosition() const override
Definition: track.h:411
void SetViaDiameter(int aDiameter)
double GetScale() const
Definition: view.h:263
wxString GetZoneName() const
Definition: zone.h:131
int Drill() const
Definition: pns_via.h:115
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
Push and Shove diff pair dimensions (gap) settings dialog.
bool ImportSizes(PNS::SIZES_SETTINGS &aSizes, PNS::ITEM *aStartItem, int aNet) override
void SetViaType(VIATYPE aViaType)
Definition: track.h:374
int GetWidth() const
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
int GetPadToDieLength() const
Definition: pad.h:376
PCB_LAYER_ID BottomLayer() const
Definition: track.cpp:463
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
bool IsFree() const
Definition: pns_via.h:118
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS *aDispOptions)
std::map< PAD *, OFFSET > m_fpOffsets
const TRIANGULATED_POLYGON * TriangulatedPolygon(int aIndex) const
DRAWINGS & Drawings()
Definition: board.h:306
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Add an item to the current node.
Definition: pns_node.cpp:615
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:73
const VECTOR2I & GetP1() const
Definition: shape_arc.h:96
FP_ZONE is a specialization of ZONE for use in footprints.
Definition: zone.h:965
TRACKS & Tracks()
Definition: board.h:300
std::shared_ptr< DRC_ENGINE > m_DRCEngine
std::unique_ptr< PNS::SEGMENT > syncTrack(TRACK *aTrack)
Represent a contiguous set of PCB layers.
Definition: pns_layerset.h:31
const LAYER_RANGE & Layers() const
Definition: pns_item.h:150
Definition: track.h:83
void SetWidth(int aWidth)
virtual double ViewGetLOD(int aLayer, VIEW *aView) const
Return the level of detail (LOD) of the item.
Definition: view_item.h:137
void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType, int aWidth, const std::string aName="") override
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:1508
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:58
bool syncZone(PNS::NODE *aWorld, ZONE *aZone, SHAPE_POLY_SET *aBoardOutline)
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:162
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
int GetNetCode() const
Definition: netinfo.h:113
VECTOR2I B
Definition: seg.h:50