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 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 
23 #include <class_board.h>
25 #include <class_module.h>
26 #include <class_track.h>
27 #include <board_commit.h>
28 #include <ratsnest_data.h>
30 #include <geometry/convex_hull.h>
31 #include <wxPcbStruct.h>
32 
33 #include <unordered_set>
34 #include <unordered_map>
35 
36 #include <view/view.h>
37 #include <view/view_item.h>
38 #include <view/view_group.h>
40 
41 #include <pcb_painter.h>
42 
43 #include <geometry/shape.h>
45 #include <geometry/shape_rect.h>
46 #include <geometry/shape_circle.h>
47 #include <geometry/shape_convex.h>
48 #include <geometry/convex_hull.h>
49 
50 
51 #include "pns_kicad_iface.h"
52 #include "pns_routing_settings.h"
53 #include "pns_sizes_settings.h"
54 #include "pns_item.h"
55 #include "pns_solid.h"
56 #include "pns_segment.h"
57 #include "pns_solid.h"
58 #include "pns_itemset.h"
59 #include "pns_node.h"
60 #include "pns_topology.h"
61 #include "pns_router.h"
62 #include "pns_debug_decorator.h"
63 #include "router_preview_item.h"
64 
66 {
67 public:
68  PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER* aRouter );
69  virtual ~PNS_PCBNEW_RULE_RESOLVER();
70 
71  virtual int Clearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) const override;
72  virtual int Clearance( int aNetCode ) const override;
73  virtual void OverrideClearance( bool aEnable, int aNetA = 0, int aNetB = 0, int aClearance = 0 ) override;
74  virtual void UseDpGap( bool aUseDpGap ) override { m_useDpGap = aUseDpGap; }
75  virtual int DpCoupledNet( int aNet ) override;
76  virtual int DpNetPolarity( int aNet ) override;
77  virtual bool DpNetPair( PNS::ITEM* aItem, int& aNetP, int& aNetN ) override;
78 
79 private:
81  {
83  int clearance;
84  };
85 
86  int localPadClearance( const PNS::ITEM* aItem ) const;
87  int matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
88 
91 
92  std::vector<CLEARANCE_ENT> m_netClearanceCache;
93  std::unordered_map<const D_PAD*, int> m_localClearanceCache;
98  bool m_useDpGap;
99 };
100 
101 
103  m_router( aRouter ),
104  m_board( aBoard )
105 {
106  PNS::NODE* world = m_router->GetWorld();
107 
108  PNS::TOPOLOGY topo( world );
110 
111  // Build clearance cache for net classes
112  for( unsigned int i = 0; i < m_board->GetNetCount(); i++ )
113  {
114  NETINFO_ITEM* ni = m_board->FindNet( i );
115 
116  if( ni == NULL )
117  continue;
118 
119  CLEARANCE_ENT ent;
120  ent.coupledNet = DpCoupledNet( i );
121 
122  wxString netClassName = ni->GetClassName();
123  NETCLASSPTR nc = m_board->GetDesignSettings().m_NetClasses.Find( netClassName );
124 
125  int clearance = nc->GetClearance();
126  ent.clearance = clearance;
127  m_netClearanceCache[i] = ent;
128 
129  wxLogTrace( "PNS", "Add net %u netclass %s clearance %d", i, netClassName.mb_str(), clearance );
130  }
131 
132  // Build clearance cache for pads
133  for( MODULE* mod = m_board->m_Modules; mod ; mod = mod->Next() )
134  {
135  auto moduleClearance = mod->GetLocalClearance();
136 
137  for( D_PAD* pad = mod->Pads(); pad; pad = pad->Next() )
138  {
139  int padClearance = pad->GetLocalClearance();
140 
141  if( padClearance > 0 )
142  m_localClearanceCache[ pad ] = padClearance;
143 
144  else if( moduleClearance > 0 )
145  m_localClearanceCache[ pad ] = moduleClearance;
146  }
147  }
148 
149  //printf("DefaultCL : %d\n", m_board->GetDesignSettings().m_NetClasses.Find ("Default clearance")->GetClearance());
150 
151  m_overrideEnabled = false;
152  m_defaultClearance = Millimeter2iu( 0.254 ); // m_board->m_NetClasses.Find ("Default clearance")->GetClearance();
153  m_overrideNetA = 0;
154  m_overrideNetB = 0;
156  m_useDpGap = false;
157 }
158 
159 
161 {
162 }
163 
164 
166 {
167  if( !aItem->Parent() || aItem->Parent()->Type() != PCB_PAD_T )
168  return 0;
169 
170  const D_PAD* pad = static_cast<D_PAD*>( aItem->Parent() );
171 
172  auto i = m_localClearanceCache.find( pad );
173 
174  if( i == m_localClearanceCache.end() )
175  return 0;
176 
177  return i->second;
178 }
179 
180 
181 int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) const
182 {
183  int net_a = aA->Net();
184  int cl_a = ( net_a >= 0 ? m_netClearanceCache[net_a].clearance : m_defaultClearance );
185  int net_b = aB->Net();
186  int cl_b = ( net_b >= 0 ? m_netClearanceCache[net_b].clearance : m_defaultClearance );
187 
188  bool linesOnly = aA->OfKind( PNS::ITEM::SEGMENT_T | PNS::ITEM::LINE_T )
190 
191  if( linesOnly && net_a >= 0 && net_b >= 0 && m_netClearanceCache[net_a].coupledNet == net_b )
192  {
193  cl_a = cl_b = m_router->Sizes().DiffPairGap() - 2 * PNS_HULL_MARGIN;
194  }
195 
196  int pad_a = localPadClearance( aA );
197  int pad_b = localPadClearance( aB );
198 
199  if( pad_a > 0 )
200  cl_a = pad_a;
201 
202  if( pad_b > 0 )
203  cl_b = pad_b;
204 
205  return std::max( cl_a, cl_b );
206 }
207 
208 
209 int PNS_PCBNEW_RULE_RESOLVER::Clearance( int aNetCode ) const
210 {
211  if( aNetCode > 0 && aNetCode < (int) m_netClearanceCache.size() )
212  return m_netClearanceCache[aNetCode].clearance;
213 
214  return m_defaultClearance;
215 }
216 
217 
218 // fixme: ugly hack to make the optimizer respect gap width for currently routed differential pair.
219 void PNS_PCBNEW_RULE_RESOLVER::OverrideClearance( bool aEnable, int aNetA, int aNetB , int aClearance )
220 {
221  m_overrideEnabled = aEnable;
222  m_overrideNetA = aNetA;
223  m_overrideNetB = aNetB;
224  m_overrideClearance = aClearance;
225 }
226 
227 
228 int PNS_PCBNEW_RULE_RESOLVER::matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
229 {
230  int rv = 0;
231 
232  if( aNetName.EndsWith( "+" ) )
233  {
234  aComplementNet = "-";
235  rv = 1;
236  }
237  else if( aNetName.EndsWith( "_P" ) )
238  {
239  aComplementNet = "_N";
240  rv = 1;
241  }
242  else if( aNetName.EndsWith( "-" ) )
243  {
244  aComplementNet = "+";
245  rv = -1;
246  }
247  else if( aNetName.EndsWith( "_N" ) )
248  {
249  aComplementNet = "_P";
250  rv = -1;
251  }
252 
253  if( rv != 0 )
254  {
255  aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
256  aComplementNet = aBaseDpName + aComplementNet;
257  }
258 
259  return rv;
260 }
261 
262 
264 {
265  wxString refName = m_board->FindNet( aNet )->GetNetname();
266  wxString dummy, coupledNetName;
267 
268  if( matchDpSuffix( refName, coupledNetName, dummy ) )
269  {
270  NETINFO_ITEM* net = m_board->FindNet( coupledNetName );
271 
272  if( !net )
273  return -1;
274 
275  return net->GetNet();
276  }
277 
278  return -1;
279 }
280 
281 
283 {
284  wxString refName = m_board->FindNet( aNet )->GetNetname();
285  wxString dummy1, dummy2;
286 
287  return matchDpSuffix( refName, dummy1, dummy2 );
288 }
289 
290 
291 bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( PNS::ITEM* aItem, int& aNetP, int& aNetN )
292 {
293  if( !aItem || !aItem->Parent() || !aItem->Parent()->GetNet() )
294  return false;
295 
296  wxString netNameP = aItem->Parent()->GetNet()->GetNetname();
297  wxString netNameN, netNameCoupled, netNameBase;
298 
299  int r = matchDpSuffix( netNameP, netNameCoupled, netNameBase );
300 
301  if( r == 0 )
302  return false;
303  else if( r == 1 )
304  {
305  netNameN = netNameCoupled;
306  }
307  else
308  {
309  netNameN = netNameP;
310  netNameP = netNameCoupled;
311  }
312 
313 // wxLogTrace( "PNS","p %s n %s base %s\n", (const char *)netNameP.c_str(), (const char *)netNameN.c_str(), (const char *)netNameBase.c_str() );
314 
315  NETINFO_ITEM* netInfoP = m_board->FindNet( netNameP );
316  NETINFO_ITEM* netInfoN = m_board->FindNet( netNameN );
317 
318  //wxLogTrace( "PNS","ip %p in %p\n", netInfoP, netInfoN);
319 
320  if( !netInfoP || !netInfoN )
321  return false;
322 
323  aNetP = netInfoP->GetNet();
324  aNetN = netInfoN->GetNet();
325 
326  return true;
327 }
328 
329 
331 {
332 public:
334  m_view( NULL ), m_items( NULL )
335  {
336  SetView( aView );
337  }
338 
340  {
341  Clear();
342  delete m_items;
343  }
344 
345  void SetView( KIGFX::VIEW* aView )
346  {
347  Clear();
348  delete m_items;
349  m_items = NULL;
350  m_view = aView;
351 
352  if( m_view == NULL )
353  return;
354 
357  m_view->Add( m_items );
358  }
359 
360  void AddPoint( VECTOR2I aP, int aColor ) override
361  {
363 
364  l.Append( aP - VECTOR2I( -50000, -50000 ) );
365  l.Append( aP + VECTOR2I( -50000, -50000 ) );
366 
367  AddLine( l, aColor, 10000 );
368 
369  l.Clear();
370  l.Append( aP - VECTOR2I( 50000, -50000 ) );
371  l.Append( aP + VECTOR2I( 50000, -50000 ) );
372 
373  AddLine( l, aColor, 10000 );
374  }
375 
376  void AddBox( BOX2I aB, int aColor ) override
377  {
379 
380  VECTOR2I o = aB.GetOrigin();
381  VECTOR2I s = aB.GetSize();
382 
383  l.Append( o );
384  l.Append( o.x + s.x, o.y );
385  l.Append( o.x + s.x, o.y + s.y );
386  l.Append( o.x, o.y + s.y );
387  l.Append( o );
388 
389  AddLine( l, aColor, 10000 );
390  }
391 
392  void AddSegment( SEG aS, int aColor ) override
393  {
395 
396  l.Append( aS.A );
397  l.Append( aS.B );
398 
399  AddLine( l, aColor, 10000 );
400  }
401 
402  void AddDirections( VECTOR2D aP, int aMask, int aColor ) override
403  {
404  BOX2I b( aP - VECTOR2I( 10000, 10000 ), VECTOR2I( 20000, 20000 ) );
405 
406  AddBox( b, aColor );
407  for( int i = 0; i < 8; i++ )
408  {
409  if( ( 1 << i ) & aMask )
410  {
411  VECTOR2I v = DIRECTION_45( ( DIRECTION_45::Directions ) i ).ToVector() * 100000;
412  AddSegment( SEG( aP, aP + v ), aColor );
413  }
414  }
415  }
416 
417  void AddLine( const SHAPE_LINE_CHAIN& aLine, int aType, int aWidth ) override
418  {
419  ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( NULL, m_view );
420 
421  pitem->Line( aLine, aWidth, aType );
422  m_items->Add( pitem ); // Should not be needed, as m_items has been passed as a parent group in alloc;
423  m_view->Update( m_items );
424  }
425 
426  void Clear() override
427  {
428  if( m_view && m_items )
429  {
430  m_items->FreeItems();
431  m_view->Update( m_items );
432  }
433  }
434 
435 private:
438 };
439 
440 
442 {
443  return m_debugDecorator;
444 }
445 
446 
448 {
449  m_ruleResolver = nullptr;
450  m_board = nullptr;
451  m_frame = nullptr;
452  m_view = nullptr;
453  m_previewItems = nullptr;
454  m_world = nullptr;
455  m_router = nullptr;
456  m_debugDecorator = nullptr;
457  m_dispOptions = nullptr;
458 }
459 
460 
462 {
463  delete m_ruleResolver;
464  delete m_debugDecorator;
465 
466  if( m_previewItems )
467  {
469  delete m_previewItems;
470  }
471 }
472 
473 
474 std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
475 {
476  LAYER_RANGE layers( 0, MAX_CU_LAYERS - 1 );
477 
478  // ignore non-copper pads
479  if( ( aPad->GetLayerSet() & LSET::AllCuMask()).none() )
480  return NULL;
481 
482  switch( aPad->GetAttribute() )
483  {
484  case PAD_ATTRIB_STANDARD:
485  break;
486 
487  case PAD_ATTRIB_SMD:
489  case PAD_ATTRIB_CONN:
490  {
491  LSET lmsk = aPad->GetLayerSet();
492  bool is_copper = false;
493 
494  for( int i = 0; i < MAX_CU_LAYERS; i++ )
495  {
496  if( lmsk[i] )
497  {
498  is_copper = true;
499 
501  layers = LAYER_RANGE( i );
502 
503  break;
504  }
505  }
506 
507  if( !is_copper )
508  return NULL;
509  }
510  break;
511 
512  default:
513  wxLogTrace( "PNS", "unsupported pad type 0x%x", aPad->GetAttribute() );
514  return NULL;
515  }
516 
517  std::unique_ptr< PNS::SOLID > solid( new PNS::SOLID );
518 
519  solid->SetLayers( layers );
520  solid->SetNet( aPad->GetNetCode() );
521  solid->SetParent( aPad );
522 
523  wxPoint wx_c = aPad->ShapePos();
524  wxSize wx_sz = aPad->GetSize();
525  wxPoint offset = aPad->GetOffset();
526 
527  VECTOR2I c( wx_c.x, wx_c.y );
528  VECTOR2I sz( wx_sz.x, wx_sz.y );
529 
530  RotatePoint( &offset, aPad->GetOrientation() );
531 
532  solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) );
533  solid->SetOffset( VECTOR2I( offset.x, offset.y ) );
534 
535  double orient = aPad->GetOrientation() / 10.0;
536 
537  if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
538  {
539  solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
540  }
541  else
542  {
543  if( orient == 0.0 || orient == 90.0 || orient == 180.0 || orient == 270.0 )
544  {
545  if( orient == 90.0 || orient == 270.0 )
546  sz = VECTOR2I( sz.y, sz.x );
547 
548  switch( aPad->GetShape() )
549  {
550  case PAD_SHAPE_OVAL:
551  if( sz.x == sz.y )
552  solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
553  else
554  {
555  VECTOR2I delta;
556 
557  if( sz.x > sz.y )
558  delta = VECTOR2I( ( sz.x - sz.y ) / 2, 0 );
559  else
560  delta = VECTOR2I( 0, ( sz.y - sz.x ) / 2 );
561 
562  SHAPE_SEGMENT* shape = new SHAPE_SEGMENT( c - delta, c + delta,
563  std::min( sz.x, sz.y ) );
564  solid->SetShape( shape );
565  }
566  break;
567 
568  case PAD_SHAPE_RECT:
569  solid->SetShape( new SHAPE_RECT( c - sz / 2, sz.x, sz.y ) );
570  break;
571 
572  case PAD_SHAPE_TRAPEZOID:
573  {
574  wxPoint coords[4];
575  aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
576  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
577 
578  for( int ii = 0; ii < 4; ii++ )
579  {
580  shape->Append( wx_c + coords[ii] );
581  }
582 
583  solid->SetShape( shape );
584  break;
585  }
586 
587  case PAD_SHAPE_ROUNDRECT:
588  {
589  SHAPE_POLY_SET outline;
590  const int segmentToCircleCount = 64;
591 
592  aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ), segmentToCircleCount, 1.0 );
593 
594  // TransformRoundRectToPolygon creates only one convex polygon
595  SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
596  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
597 
598  for( int ii = 0; ii < poly.PointCount(); ++ii )
599  {
600  shape->Append( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
601  }
602 
603  solid->SetShape( shape );
604  }
605  break;
606 
607  default:
608  wxLogTrace( "PNS", "unsupported pad shape" );
609  return nullptr;
610  }
611  }
612  else
613  {
614  switch( aPad->GetShape() )
615  {
616  // PAD_SHAPE_CIRCLE already handled above
617 
618  case PAD_SHAPE_OVAL:
619  if( sz.x == sz.y )
620  solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
621  else
622  {
623  wxPoint start;
624  wxPoint end;
625  wxPoint corner;
626 
627  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
628 
629  int w = aPad->BuildSegmentFromOvalShape( start, end, 0.0, wxSize( 0, 0 ) );
630 
631  if( start.y == 0 )
632  corner = wxPoint( start.x, -( w / 2 ) );
633  else
634  corner = wxPoint( w / 2, start.y );
635 
636  RotatePoint( &start, aPad->GetOrientation() );
637  RotatePoint( &corner, aPad->GetOrientation() );
638  shape->Append( wx_c + corner );
639 
640  for( int rot = 100; rot <= 1800; rot += 100 )
641  {
642  wxPoint p( corner );
643  RotatePoint( &p, start, rot );
644  shape->Append( wx_c + p );
645  }
646 
647  if( end.y == 0 )
648  corner = wxPoint( end.x, w / 2 );
649  else
650  corner = wxPoint( -( w / 2 ), end.y );
651 
652  RotatePoint( &end, aPad->GetOrientation() );
653  RotatePoint( &corner, aPad->GetOrientation() );
654  shape->Append( wx_c + corner );
655 
656  for( int rot = 100; rot <= 1800; rot += 100 )
657  {
658  wxPoint p( corner );
659  RotatePoint( &p, end, rot );
660  shape->Append( wx_c + p );
661  }
662 
663  solid->SetShape( shape );
664  }
665  break;
666 
667  case PAD_SHAPE_RECT:
668  case PAD_SHAPE_TRAPEZOID:
669  {
670  wxPoint coords[4];
671  aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
672 
673  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
674  for( int ii = 0; ii < 4; ii++ )
675  {
676  shape->Append( wx_c + coords[ii] );
677  }
678 
679  solid->SetShape( shape );
680  break;
681  }
682 
683  case PAD_SHAPE_ROUNDRECT:
684  {
685  SHAPE_POLY_SET outline;
686  const int segmentToCircleCount = 32;
687  aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ),
688  segmentToCircleCount, 1.0 );
689 
690  // TransformRoundRectToPolygon creates only one convex polygon
691  SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
692  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
693 
694  for( int ii = 0; ii < poly.PointCount(); ++ii )
695  {
696  shape->Append( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
697  }
698 
699  solid->SetShape( shape );
700  break;
701  }
702 
703  default:
704  wxLogTrace( "PNS", "unsupported pad shape" );
705  return nullptr;
706  }
707  }
708  }
709  return solid;
710 }
711 
712 
713 std::unique_ptr<PNS::SEGMENT> PNS_KICAD_IFACE::syncTrack( TRACK* aTrack )
714 {
715  std::unique_ptr< PNS::SEGMENT > segment(
716  new PNS::SEGMENT( SEG( aTrack->GetStart(), aTrack->GetEnd() ), aTrack->GetNetCode() )
717  );
718 
719  segment->SetWidth( aTrack->GetWidth() );
720  segment->SetLayers( LAYER_RANGE( aTrack->GetLayer() ) );
721  segment->SetParent( aTrack );
722 
723  if( aTrack->IsLocked() )
724  segment->Mark( PNS::MK_LOCKED );
725 
726  return segment;
727 }
728 
729 
730 std::unique_ptr<PNS::VIA> PNS_KICAD_IFACE::syncVia( VIA* aVia )
731 {
732  PCB_LAYER_ID top, bottom;
733  aVia->LayerPair( &top, &bottom );
734  std::unique_ptr<PNS::VIA> via( new PNS::VIA(
735  aVia->GetPosition(),
736  LAYER_RANGE( top, bottom ),
737  aVia->GetWidth(),
738  aVia->GetDrillValue(),
739  aVia->GetNetCode(),
740  aVia->GetViaType() )
741  );
742 
743  via->SetParent( aVia );
744 
745  if( aVia->IsLocked() )
746  via->Mark( PNS::MK_LOCKED );
747 
748  return via;
749 }
750 
751 
753 {
754  m_board = aBoard;
755  wxLogTrace( "PNS", "m_board = %p", m_board );
756 }
757 
758 
760 {
761  if( !m_board )
762  {
763  wxLogTrace( "PNS", "No board attached, aborting sync." );
764  return;
765  }
766 
767  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
768  {
769  for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
770  {
771  std::unique_ptr< PNS::SOLID > solid = syncPad( pad );
772 
773  if( solid )
774  aWorld->Add( std::move( solid ) );
775  }
776  }
777 
778  for( TRACK* t = m_board->m_Track; t; t = t->Next() )
779  {
780  KICAD_T type = t->Type();
781 
782  if( type == PCB_TRACE_T ) {
783  std::unique_ptr< PNS::SEGMENT > segment = syncTrack( t );
784  if( segment ) {
785  aWorld->Add( std::move( segment ) );
786  }
787  } else if( type == PCB_VIA_T ) {
788  std::unique_ptr< PNS::VIA > via = syncVia( static_cast<VIA*>( t ) );
789  if( via ) {
790  aWorld->Add( std::move( via ) );
791  }
792  }
793  }
794 
795  int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
796 
797  delete m_ruleResolver;
799 
800  aWorld->SetRuleResolver( m_ruleResolver );
801  aWorld->SetMaxClearance( 4 * worstClearance );
802 }
803 
804 
806 {
807  for( auto item : m_hiddenItems )
808  m_view->SetVisible( item, true );
809 
810  m_hiddenItems.clear();
811 
812  if( m_previewItems )
813  {
816  }
817 
818  if( m_debugDecorator )
820 }
821 
822 
823 void PNS_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aColor, int aClearance )
824 {
825  wxLogTrace( "PNS", "DisplayItem %p", aItem );
826 
827  ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_view );
828 
829  if( aColor >= 0 )
830  pitem->SetColor( KIGFX::COLOR4D( aColor ) );
831 
832  if( aClearance >= 0 )
833  {
834  pitem->SetClearance( aClearance );
835 
836  if( m_dispOptions )
837  {
838  auto clearanceDisp = m_dispOptions->m_ShowTrackClearanceMode;
839  pitem->ShowTrackClearance( clearanceDisp != DO_NOT_SHOW_CLEARANCE );
840  pitem->ShowViaClearance( clearanceDisp != DO_NOT_SHOW_CLEARANCE
841  && clearanceDisp != SHOW_CLEARANCE_NEW_TRACKS );
842  }
843  }
844 
845 
846  m_previewItems->Add( pitem );
848 }
849 
850 
852 {
853  BOARD_CONNECTED_ITEM* parent = aItem->Parent();
854 
855  if( parent )
856  {
857  if( m_view->IsVisible( parent ) )
858  m_hiddenItems.insert( parent );
859 
860  m_view->SetVisible( parent, false );
861  m_view->Update( parent, KIGFX::APPEARANCE );
862  }
863 }
864 
865 
867 {
868  BOARD_CONNECTED_ITEM* parent = aItem->Parent();
869 
870  if( parent )
871  {
872  m_commit->Remove( parent );
873  }
874 }
875 
876 
878 {
879  BOARD_CONNECTED_ITEM* newBI = NULL;
880 
881  switch( aItem->Kind() )
882  {
884  {
885  PNS::SEGMENT* seg = static_cast<PNS::SEGMENT*>( aItem );
886  TRACK* track = new TRACK( m_board );
887  const SEG& s = seg->Seg();
888  track->SetStart( wxPoint( s.A.x, s.A.y ) );
889  track->SetEnd( wxPoint( s.B.x, s.B.y ) );
890  track->SetWidth( seg->Width() );
891  track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) );
892  track->SetNetCode( seg->Net() > 0 ? seg->Net() : 0 );
893  newBI = track;
894  break;
895  }
896 
897  case PNS::ITEM::VIA_T:
898  {
899  VIA* via_board = new VIA( m_board );
900  PNS::VIA* via = static_cast<PNS::VIA*>( aItem );
901  via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) );
902  via_board->SetWidth( via->Diameter() );
903  via_board->SetDrill( via->Drill() );
904  via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 );
905  via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
906  via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
907  ToLAYER_ID( via->Layers().End() ) );
908  newBI = via_board;
909  break;
910  }
911 
912  default:
913  break;
914  }
915 
916  if( newBI )
917  {
918  aItem->SetParent( newBI );
919  newBI->ClearFlags();
920 
921  m_commit->Add( newBI );
922  }
923 }
924 
925 
927 {
928  EraseView();
929  m_commit->Push( wxT( "Added a track" ) );
930  m_commit.reset( new BOARD_COMMIT( m_frame ) );
931 }
932 
933 
935 {
936  wxLogTrace( "PNS", "SetView %p", aView );
937 
938  if( m_previewItems )
939  {
941  delete m_previewItems;
942  }
943 
944  m_view = aView;
948 
949  delete m_debugDecorator;
952 }
953 
954 
955 void PNS_KICAD_IFACE::UpdateNet( int aNetCode )
956 {
957  wxLogTrace( "PNS", "Update-net %d", aNetCode );
958 }
959 
960 
962 {
963  return m_ruleResolver;
964 }
965 
966 
968 {
969  m_router = aRouter;
970 }
971 
972 
974 {
975  m_frame = aFrame;
976 
977  m_commit.reset( new BOARD_COMMIT( m_frame ) );
979 }
bool IsLocked() const override
Function IsLocked.
Definition: class_track.h:136
const VECTOR2I ToVector() const
Function ToVector()
Definition: direction45.h:295
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:639
const Vec & GetOrigin() const
Definition: box2.h:181
Class ITEM.
Definition: pns_item.h:53
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
int matchDpSuffix(wxString aNetName, wxString &aComplementNet, wxString &aBaseDpName)
Class BOARD_CONNECTED_ITEM.
void SetView(KIGFX::VIEW *aView)
virtual bool DpNetPair(PNS::ITEM *aItem, int &aNetP, int &aNetN) override
NETCLASSPTR Find(const wxString &aName) const
Function Find searches this container for a NETCLASS given by aName.
PNS_PCBNEW_DEBUG_DECORATOR * m_debugDecorator
Class NODE.
Definition: pns_node.h:137
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:238
void SetViaType(VIATYPE_T aViaType)
Definition: class_track.h:447
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:207
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:63
void SetPosition(const wxPoint &aPoint) override
Definition: class_track.h:417
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:117
PNS::NODE * m_world
int GetBiggestClearanceValue()
Function GetBiggestClearanceValue.
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
int PointCount() const
Function PointCount()
void AddPoint(VECTOR2I aP, int aColor) override
int Drill() const
Definition: pns_via.h:120
Class BOARD to handle a board.
Class that computes missing connections on a PCB.
int Diameter() const
Definition: pns_via.h:109
std::unordered_set< BOARD_CONNECTED_ITEM * > m_hiddenItems
std::unique_ptr< PNS::SOLID > syncPad(D_PAD *aPad)
void UpdateNet(int aNetCode) override
void AddBox(BOX2I aB, int aColor) override
MODULE * Next() const
Definition: class_module.h:100
void SetRouter(PNS::ROUTER *aRouter) override
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:59
int localPadClearance(const PNS::ITEM *aItem) const
#define PNS_HULL_MARGIN
Class LINE.
Definition: pns_line.h:58
void SetClearance(int aClearance)
class D_PAD, a pad in a footprint
Definition: typeinfo.h:102
Class SHAPE_CONVEX.
Definition: shape_convex.h:42
No updates are required.
Definition: view_item.h:55
Class RULE_RESOLVER.
Definition: pns_node.h:56
PNS_PCBNEW_DEBUG_DECORATOR(KIGFX::VIEW *aView=NULL)
void Line(const SHAPE_LINE_CHAIN &aLine, int aWidth=0, int aStyle=0)
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
void ShowTrackClearance(bool aEnabled)
std::unique_ptr< PNS::SEGMENT > syncTrack(TRACK *aTrack)
const VECTOR2I & Pos() const
Definition: pns_via.h:88
void SetRuleResolver(RULE_RESOLVER *aFunc)
Assigns a clerance resolution function object
Definition: pns_node.h:163
SIZES_SETTINGS & Sizes()
Definition: pns_router.h:197
const Vec & GetSize() const
Definition: box2.h:177
void HideItem(PNS::ITEM *aItem) override
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:166
PNS::DEBUG_DECORATOR * GetDebugDecorator() override
Class BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected an...
static const int delta[8][2]
Definition: solve.cpp:112
const wxPoint & GetEnd() const
Definition: class_track.h:118
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:90
NODE * GetWorld() const
Definition: pns_router.h:134
Functions relatives to tracks, vias and segments used to fill zones.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:107
void * GetDisplayOptions() override
Function GetDisplayOptions returns the display options current in use Display options are relative to...
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
KIGFX::VIEW_GROUP * m_items
void SetWidth(int aWidth)
Definition: class_track.h:114
virtual int DpNetPolarity(int aNet) override
void SetMaxClearance(int aClearance)
Sets the worst-case clerance between any pair of items
Definition: pns_node.h:157
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:130
VIATYPE_T ViaType() const
Definition: pns_via.h:99
void SetHostFrame(PCB_EDIT_FRAME *aFrame)
int End() const
Definition: pns_layerset.h:88
void SetParent(BOARD_CONNECTED_ITEM *aParent)
Function SetParent()
Definition: pns_item.h:147
PCB_LAYER_ID
A quick note on layer IDs:
void FreeItems()
Function FreeItems() Frees all the items that were added to the group.
Definition: view_group.cpp:141
void Append(int aX, int aY)
Function Append()
Definition: shape_convex.h:151
Class LSET is a set of PCB_LAYER_IDs.
VIEW_ITEM class definition.
VIATYPE_T GetViaType() const
Definition: class_track.h:446
Class SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
std::unique_ptr< BOARD_COMMIT > m_commit
Class DIRECTION_45.
Definition: direction45.h:33
const wxPoint & GetStart() const
Definition: class_track.h:121
virtual int DpCoupledNet(int aNet) override
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:235
PCB_EDIT_FRAME * m_frame
D_PAD * Next() const
Definition: class_pad.h:106
void ShowViaClearance(bool aEnabled)
std::vector< CLEARANCE_ENT > m_netClearanceCache
const wxSize & GetSize() const
Definition: class_pad.h:182
PNS_PCBNEW_RULE_RESOLVER * m_ruleResolver
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
bool SetNetCode(int aNetCode, bool aNoAssert=false)
Function SetNetCode sets net using a net code.
VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object.
general purpose overlay
KIGFX::VIEW_GROUP * m_previewItems
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...
int Width() const
Definition: pns_segment.h:88
int Start() const
Definition: pns_layerset.h:83
int GetNet() const
Function GetNet.
virtual void Add(VIEW_ITEM *aItem)
Function Add() Adds an item to the group.
Definition: view_group.cpp:55
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:60
void SetColor(const KIGFX::COLOR4D &aColor)
PNS::ROUTER * m_router
void Update(VIEW_ITEM *aItem)
Function Update() For dynamic VIEWs, informs the associated VIEW that the graphical representation of...
Definition: view.cpp:1379
virtual void SetLayer(int aLayer)
Function SetLayer() Sets layer used to draw the group.
Definition: view_group.h:115
void DisplayItem(const PNS::ITEM *aItem, int aColor=0, int aClearance=0) override
void Commit() override
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...
Class DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
Definition: pcbstruct.h:62
PNS::RULE_RESOLVER * GetRuleResolver() override
PnsKind Kind() const
Function Kind()
Definition: pns_item.h:120
void EraseView() override
int GetNetCode() const
Function GetNetCode.
Definition: seg.h:37
TRACE_CLEARANCE_DISPLAY_MODE_T m_ShowTrackClearanceMode
How trace clearances are displayed.
Definition: pcbstruct.h:74
KIGFX::VIEW * m_view
Class NETINFO_ITEM handles the data for a net.
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int BuildSegmentFromOvalShape(wxPoint &aSegStart, wxPoint &aSegEnd, double aRotation, const wxSize &aMargin) const
Function BuildSegmentFromOvalShape Has meaning only for OVAL (and ROUND) pads Build an equivalent seg...
void SyncWorld(PNS::NODE *aWorld) override
TRACK * Next() const
Definition: class_track.h:98
const wxString & GetClassName() const
Function GetClassName returns the class name.
Board layer functions and definitions.
DISPLAY_OPTIONS * m_dispOptions
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
DLIST< MODULE > m_Modules
Definition: class_board.h:243
Class SHAPE_LINE_CHAIN.
void RemoveItem(PNS::ITEM *aItem) override
int GetWidth() const
Definition: class_track.h:115
std::unique_ptr< PNS::VIA > syncVia(VIA *aVia)
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:214
VECTOR2I A
Definition: seg.h:47
void AddItem(PNS::ITEM *aItem) override
void SetDrill(int aDrill)
Function SetDrill sets the drill value for vias.
Definition: class_track.h:454
void SetView(KIGFX::VIEW *aView)
Usual pad.
Definition: pad_shapes.h:58
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
int Net() const
Function Net()
Definition: pns_item.h:177
virtual void OverrideClearance(bool aEnable, int aNetA=0, int aNetB=0, int aClearance=0) override
void BuildPadShapePolygon(SHAPE_POLY_SET &aCornerBuffer, wxSize aInflateValue, int aSegmentsPerCircle, double aCorrectionFactor) const
Function BuildPadShapePolygon Build the Corner list of the polygonal shape, depending on shape...
const wxPoint & GetPosition() const override
Definition: class_track.h:416
wxPoint ShapePos() const
Definition: class_pad.cpp:367
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:254
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Function SetVisible() Sets the item visibility.
Definition: view.cpp:1331
void Clear()
Function Clear() Removes all points from the line chain.
void SetStart(const wxPoint &aStart)
Definition: class_track.h:120
const SEG & Seg() const
Definition: pns_segment.h:93
VECTOR2I & Point(int aIndex)
Function Point()
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:311
void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType, int aWidth) override
DLIST< TRACK > m_Track
Definition: class_board.h:244
Module description (excepted pads)
const wxString & GetNetname() const
Function GetNetname.
void AddDirections(VECTOR2D aP, int aMask, int aColor) override
virtual int Clearance(const PNS::ITEM *aA, const PNS::ITEM *aB) const override
Class VIEW.
Definition: view.h:58
bool IsVisible(const VIEW_ITEM *aItem) const
Function IsVisible() Returns information if the item is visible (or not).
Definition: view.cpp:1371
virtual void UseDpGap(bool aUseDpGap) override
Directions
Enum Directions Represents available directions - there are 8 of them, as on a rectilinear map (north...
Definition: direction45.h:42
void AddSegment(SEG aS, int aColor) override
Push and Shove diff pair dimensions (gap) settings dialog.
void SetBoard(BOARD *aBoard)
void Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Function Add()
Definition: pns_node.cpp:596
std::unordered_map< const D_PAD *, int > m_localClearanceCache
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:767
#define mod(a, n)
Definition: greymap.cpp:24
PNS_PCBNEW_RULE_RESOLVER(BOARD *aBoard, PNS::ROUTER *aRouter)
const wxPoint & GetOffset() const
Definition: class_pad.h:191
BOARD_CONNECTED_ITEM * Parent() const
Function Parent()
Definition: pns_item.h:157
NETINFO_ITEM * GetNet() const
Function GetNet Returns NET_INFO object for a given item.
Class LAYER_RANGE.
Definition: pns_layerset.h:32
NETCLASSES m_NetClasses
List of current netclasses. There is always the default netclass.
unsigned GetNetCount() const
Function GetNetCount.
Definition: class_board.h:814
#define min(a, b)
Definition: auxiliary.h:85
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
VECTOR2I B
Definition: seg.h:48