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>
29 #include <geometry/convex_hull.h>
30 #include <wxPcbStruct.h>
31 
32 #include <unordered_set>
33 #include <unordered_map>
34 
35 #include <view/view.h>
36 #include <view/view_item.h>
37 #include <view/view_group.h>
39 
40 #include <pcb_painter.h>
41 
42 #include <geometry/shape.h>
44 #include <geometry/shape_rect.h>
45 #include <geometry/shape_circle.h>
46 #include <geometry/shape_convex.h>
47 #include <geometry/convex_hull.h>
48 
49 
50 #include "pns_kicad_iface.h"
51 #include "pns_routing_settings.h"
52 #include "pns_sizes_settings.h"
53 #include "pns_item.h"
54 #include "pns_solid.h"
55 #include "pns_segment.h"
56 #include "pns_solid.h"
57 #include "pns_itemset.h"
58 #include "pns_node.h"
59 #include "pns_topology.h"
60 #include "pns_router.h"
61 #include "pns_debug_decorator.h"
62 #include "router_preview_item.h"
63 
65 {
66 public:
67  PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER* aRouter );
68  virtual ~PNS_PCBNEW_RULE_RESOLVER();
69 
70  virtual int Clearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) const override;
71  virtual int Clearance( int aNetCode ) const override;
72  virtual void OverrideClearance( bool aEnable, int aNetA = 0, int aNetB = 0, int aClearance = 0 ) override;
73  virtual void UseDpGap( bool aUseDpGap ) override { m_useDpGap = aUseDpGap; }
74  virtual int DpCoupledNet( int aNet ) override;
75  virtual int DpNetPolarity( int aNet ) override;
76  virtual bool DpNetPair( PNS::ITEM* aItem, int& aNetP, int& aNetN ) override;
77 
78 private:
80  {
82  int clearance;
83  };
84 
85  int localPadClearance( const PNS::ITEM* aItem ) const;
86  int matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName );
87 
90 
91  std::vector<CLEARANCE_ENT> m_netClearanceCache;
92  std::unordered_map<const D_PAD*, int> m_localClearanceCache;
97  bool m_useDpGap;
98 };
99 
100 
102  m_router( aRouter ),
103  m_board( aBoard )
104 {
105  PNS::NODE* world = m_router->GetWorld();
106 
107  PNS::TOPOLOGY topo( world );
109 
110  // Build clearance cache for net classes
111  for( unsigned int i = 0; i < m_board->GetNetCount(); i++ )
112  {
113  NETINFO_ITEM* ni = m_board->FindNet( i );
114 
115  if( ni == NULL )
116  continue;
117 
118  CLEARANCE_ENT ent;
119  ent.coupledNet = DpCoupledNet( i );
120 
121  wxString netClassName = ni->GetClassName();
122  NETCLASSPTR nc = m_board->GetDesignSettings().m_NetClasses.Find( netClassName );
123 
124  int clearance = nc->GetClearance();
125  ent.clearance = clearance;
126  m_netClearanceCache[i] = ent;
127 
128  wxLogTrace( "PNS", "Add net %u netclass %s clearance %d", i, netClassName.mb_str(), clearance );
129  }
130 
131  // Build clearance cache for pads
132  for( MODULE* mod = m_board->m_Modules; mod ; mod = mod->Next() )
133  {
134  auto moduleClearance = mod->GetLocalClearance();
135 
136  for( D_PAD* pad = mod->PadsList(); pad; pad = pad->Next() )
137  {
138  int padClearance = pad->GetLocalClearance();
139 
140  if( padClearance > 0 )
141  m_localClearanceCache[ pad ] = padClearance;
142 
143  else if( moduleClearance > 0 )
144  m_localClearanceCache[ pad ] = moduleClearance;
145  }
146  }
147 
148  //printf("DefaultCL : %d\n", m_board->GetDesignSettings().m_NetClasses.Find ("Default clearance")->GetClearance());
149 
150  m_overrideEnabled = false;
151  m_defaultClearance = Millimeter2iu( 0.254 ); // m_board->m_NetClasses.Find ("Default clearance")->GetClearance();
152  m_overrideNetA = 0;
153  m_overrideNetB = 0;
155  m_useDpGap = false;
156 }
157 
158 
160 {
161 }
162 
163 
165 {
166  if( !aItem->Parent() || aItem->Parent()->Type() != PCB_PAD_T )
167  return 0;
168 
169  const D_PAD* pad = static_cast<D_PAD*>( aItem->Parent() );
170 
171  auto i = m_localClearanceCache.find( pad );
172 
173  if( i == m_localClearanceCache.end() )
174  return 0;
175 
176  return i->second;
177 }
178 
179 
180 int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* aB ) const
181 {
182  int net_a = aA->Net();
183  int cl_a = ( net_a >= 0 ? m_netClearanceCache[net_a].clearance : m_defaultClearance );
184  int net_b = aB->Net();
185  int cl_b = ( net_b >= 0 ? m_netClearanceCache[net_b].clearance : m_defaultClearance );
186 
187  bool linesOnly = aA->OfKind( PNS::ITEM::SEGMENT_T | PNS::ITEM::LINE_T )
189 
190  if( linesOnly && net_a >= 0 && net_b >= 0 && m_netClearanceCache[net_a].coupledNet == net_b )
191  {
192  cl_a = cl_b = m_router->Sizes().DiffPairGap() - 2 * PNS_HULL_MARGIN;
193  }
194 
195  int pad_a = localPadClearance( aA );
196  int pad_b = localPadClearance( aB );
197 
198  if( pad_a > 0 )
199  cl_a = pad_a;
200 
201  if( pad_b > 0 )
202  cl_b = pad_b;
203 
204  return std::max( cl_a, cl_b );
205 }
206 
207 
208 int PNS_PCBNEW_RULE_RESOLVER::Clearance( int aNetCode ) const
209 {
210  if( aNetCode > 0 && aNetCode < (int) m_netClearanceCache.size() )
211  return m_netClearanceCache[aNetCode].clearance;
212 
213  return m_defaultClearance;
214 }
215 
216 
217 // fixme: ugly hack to make the optimizer respect gap width for currently routed differential pair.
218 void PNS_PCBNEW_RULE_RESOLVER::OverrideClearance( bool aEnable, int aNetA, int aNetB , int aClearance )
219 {
220  m_overrideEnabled = aEnable;
221  m_overrideNetA = aNetA;
222  m_overrideNetB = aNetB;
223  m_overrideClearance = aClearance;
224 }
225 
226 
227 int PNS_PCBNEW_RULE_RESOLVER::matchDpSuffix( wxString aNetName, wxString& aComplementNet, wxString& aBaseDpName )
228 {
229  int rv = 0;
230 
231  if( aNetName.EndsWith( "+" ) )
232  {
233  aComplementNet = "-";
234  rv = 1;
235  }
236  else if( aNetName.EndsWith( "_P" ) )
237  {
238  aComplementNet = "_N";
239  rv = 1;
240  }
241  else if( aNetName.EndsWith( "-" ) )
242  {
243  aComplementNet = "+";
244  rv = -1;
245  }
246  else if( aNetName.EndsWith( "_N" ) )
247  {
248  aComplementNet = "_P";
249  rv = -1;
250  }
251 
252  if( rv != 0 )
253  {
254  aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
255  aComplementNet = aBaseDpName + aComplementNet;
256  }
257 
258  return rv;
259 }
260 
261 
263 {
264  wxString refName = m_board->FindNet( aNet )->GetNetname();
265  wxString dummy, coupledNetName;
266 
267  if( matchDpSuffix( refName, coupledNetName, dummy ) )
268  {
269  NETINFO_ITEM* net = m_board->FindNet( coupledNetName );
270 
271  if( !net )
272  return -1;
273 
274  return net->GetNet();
275  }
276 
277  return -1;
278 }
279 
280 
282 {
283  wxString refName = m_board->FindNet( aNet )->GetNetname();
284  wxString dummy1, dummy2;
285 
286  return matchDpSuffix( refName, dummy1, dummy2 );
287 }
288 
289 
290 bool PNS_PCBNEW_RULE_RESOLVER::DpNetPair( PNS::ITEM* aItem, int& aNetP, int& aNetN )
291 {
292  if( !aItem || !aItem->Parent() || !aItem->Parent()->GetNet() )
293  return false;
294 
295  wxString netNameP = aItem->Parent()->GetNet()->GetNetname();
296  wxString netNameN, netNameCoupled, netNameBase;
297 
298  int r = matchDpSuffix( netNameP, netNameCoupled, netNameBase );
299 
300  if( r == 0 )
301  return false;
302  else if( r == 1 )
303  {
304  netNameN = netNameCoupled;
305  }
306  else
307  {
308  netNameN = netNameP;
309  netNameP = netNameCoupled;
310  }
311 
312 // wxLogTrace( "PNS","p %s n %s base %s\n", (const char *)netNameP.c_str(), (const char *)netNameN.c_str(), (const char *)netNameBase.c_str() );
313 
314  NETINFO_ITEM* netInfoP = m_board->FindNet( netNameP );
315  NETINFO_ITEM* netInfoN = m_board->FindNet( netNameN );
316 
317  //wxLogTrace( "PNS","ip %p in %p\n", netInfoP, netInfoN);
318 
319  if( !netInfoP || !netInfoN )
320  return false;
321 
322  aNetP = netInfoP->GetNet();
323  aNetN = netInfoN->GetNet();
324 
325  return true;
326 }
327 
328 
330 {
331 public:
333  m_view( NULL ), m_items( NULL )
334  {
335  SetView( aView );
336  }
337 
339  {
340  Clear();
341  delete m_items;
342  }
343 
344  void SetView( KIGFX::VIEW* aView )
345  {
346  Clear();
347  delete m_items;
348  m_items = NULL;
349  m_view = aView;
350 
351  if( m_view == NULL )
352  return;
353 
356  m_view->Add( m_items );
357  }
358 
359  void AddPoint( VECTOR2I aP, int aColor ) override
360  {
362 
363  l.Append( aP - VECTOR2I( -50000, -50000 ) );
364  l.Append( aP + VECTOR2I( -50000, -50000 ) );
365 
366  AddLine( l, aColor, 10000 );
367 
368  l.Clear();
369  l.Append( aP - VECTOR2I( 50000, -50000 ) );
370  l.Append( aP + VECTOR2I( 50000, -50000 ) );
371 
372  AddLine( l, aColor, 10000 );
373  }
374 
375  void AddBox( BOX2I aB, int aColor ) override
376  {
378 
379  VECTOR2I o = aB.GetOrigin();
380  VECTOR2I s = aB.GetSize();
381 
382  l.Append( o );
383  l.Append( o.x + s.x, o.y );
384  l.Append( o.x + s.x, o.y + s.y );
385  l.Append( o.x, o.y + s.y );
386  l.Append( o );
387 
388  AddLine( l, aColor, 10000 );
389  }
390 
391  void AddSegment( SEG aS, int aColor ) override
392  {
394 
395  l.Append( aS.A );
396  l.Append( aS.B );
397 
398  AddLine( l, aColor, 10000 );
399  }
400 
401  void AddDirections( VECTOR2D aP, int aMask, int aColor ) override
402  {
403  BOX2I b( aP - VECTOR2I( 10000, 10000 ), VECTOR2I( 20000, 20000 ) );
404 
405  AddBox( b, aColor );
406  for( int i = 0; i < 8; i++ )
407  {
408  if( ( 1 << i ) & aMask )
409  {
410  VECTOR2I v = DIRECTION_45( ( DIRECTION_45::Directions ) i ).ToVector() * 100000;
411  AddSegment( SEG( aP, aP + v ), aColor );
412  }
413  }
414  }
415 
416  void AddLine( const SHAPE_LINE_CHAIN& aLine, int aType, int aWidth ) override
417  {
418  ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( NULL, m_view );
419 
420  pitem->Line( aLine, aWidth, aType );
421  m_items->Add( pitem ); // Should not be needed, as m_items has been passed as a parent group in alloc;
422  m_view->Update( m_items );
423  }
424 
425  void Clear() override
426  {
427  if( m_view && m_items )
428  {
429  m_items->FreeItems();
430  m_view->Update( m_items );
431  }
432  }
433 
434 private:
437 };
438 
439 
441 {
442  return m_debugDecorator;
443 }
444 
445 
447 {
448  m_ruleResolver = nullptr;
449  m_board = nullptr;
450  m_frame = nullptr;
451  m_view = nullptr;
452  m_previewItems = nullptr;
453  m_world = nullptr;
454  m_router = nullptr;
455  m_debugDecorator = nullptr;
456  m_dispOptions = nullptr;
457 }
458 
459 
461 {
462  delete m_ruleResolver;
463  delete m_debugDecorator;
464 
465  if( m_previewItems )
466  {
468  delete m_previewItems;
469  }
470 }
471 
472 
473 std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
474 {
475  LAYER_RANGE layers( 0, MAX_CU_LAYERS - 1 );
476 
477  // ignore non-copper pads
478  if( ( aPad->GetLayerSet() & LSET::AllCuMask()).none() )
479  return NULL;
480 
481  switch( aPad->GetAttribute() )
482  {
483  case PAD_ATTRIB_STANDARD:
484  break;
485 
486  case PAD_ATTRIB_SMD:
488  case PAD_ATTRIB_CONN:
489  {
490  LSET lmsk = aPad->GetLayerSet();
491  bool is_copper = false;
492 
493  for( int i = 0; i < MAX_CU_LAYERS; i++ )
494  {
495  if( lmsk[i] )
496  {
497  is_copper = true;
498 
500  layers = LAYER_RANGE( i );
501 
502  break;
503  }
504  }
505 
506  if( !is_copper )
507  return NULL;
508  }
509  break;
510 
511  default:
512  wxLogTrace( "PNS", "unsupported pad type 0x%x", aPad->GetAttribute() );
513  return NULL;
514  }
515 
516  std::unique_ptr< PNS::SOLID > solid( new PNS::SOLID );
517 
518  solid->SetLayers( layers );
519  solid->SetNet( aPad->GetNetCode() );
520  solid->SetParent( aPad );
521 
522  wxPoint wx_c = aPad->ShapePos();
523  wxSize wx_sz = aPad->GetSize();
524  wxPoint offset = aPad->GetOffset();
525 
526  VECTOR2I c( wx_c.x, wx_c.y );
527  VECTOR2I sz( wx_sz.x, wx_sz.y );
528 
529  RotatePoint( &offset, aPad->GetOrientation() );
530 
531  solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) );
532  solid->SetOffset( VECTOR2I( offset.x, offset.y ) );
533 
534  double orient = aPad->GetOrientation() / 10.0;
535 
536  if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
537  {
538  solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
539  }
540  else
541  {
542  if( orient == 0.0 || orient == 90.0 || orient == 180.0 || orient == 270.0 )
543  {
544  if( orient == 90.0 || orient == 270.0 )
545  sz = VECTOR2I( sz.y, sz.x );
546 
547  switch( aPad->GetShape() )
548  {
549  case PAD_SHAPE_OVAL:
550  if( sz.x == sz.y )
551  solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
552  else
553  {
554  VECTOR2I delta;
555 
556  if( sz.x > sz.y )
557  delta = VECTOR2I( ( sz.x - sz.y ) / 2, 0 );
558  else
559  delta = VECTOR2I( 0, ( sz.y - sz.x ) / 2 );
560 
561  SHAPE_SEGMENT* shape = new SHAPE_SEGMENT( c - delta, c + delta,
562  std::min( sz.x, sz.y ) );
563  solid->SetShape( shape );
564  }
565  break;
566 
567  case PAD_SHAPE_RECT:
568  solid->SetShape( new SHAPE_RECT( c - sz / 2, sz.x, sz.y ) );
569  break;
570 
571  case PAD_SHAPE_TRAPEZOID:
572  {
573  wxPoint coords[4];
574  aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
575  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
576 
577  for( int ii = 0; ii < 4; ii++ )
578  {
579  shape->Append( wx_c + coords[ii] );
580  }
581 
582  solid->SetShape( shape );
583  break;
584  }
585 
586  case PAD_SHAPE_ROUNDRECT:
587  {
588  SHAPE_POLY_SET outline;
589  const int segmentToCircleCount = 64;
590 
591  aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ), segmentToCircleCount, 1.0 );
592 
593  // TransformRoundRectToPolygon creates only one convex polygon
594  SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
595  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
596 
597  for( int ii = 0; ii < poly.PointCount(); ++ii )
598  {
599  shape->Append( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
600  }
601 
602  solid->SetShape( shape );
603  }
604  break;
605 
606  default:
607  wxLogTrace( "PNS", "unsupported pad shape" );
608  return nullptr;
609  }
610  }
611  else
612  {
613  switch( aPad->GetShape() )
614  {
615  // PAD_SHAPE_CIRCLE already handled above
616 
617  case PAD_SHAPE_OVAL:
618  if( sz.x == sz.y )
619  solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
620  else
621  {
622  wxPoint start;
623  wxPoint end;
624  wxPoint corner;
625 
626  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
627 
628  int w = aPad->BuildSegmentFromOvalShape( start, end, 0.0, wxSize( 0, 0 ) );
629 
630  if( start.y == 0 )
631  corner = wxPoint( start.x, -( w / 2 ) );
632  else
633  corner = wxPoint( w / 2, start.y );
634 
635  RotatePoint( &start, aPad->GetOrientation() );
636  RotatePoint( &corner, aPad->GetOrientation() );
637  shape->Append( wx_c + corner );
638 
639  for( int rot = 100; rot <= 1800; rot += 100 )
640  {
641  wxPoint p( corner );
642  RotatePoint( &p, start, rot );
643  shape->Append( wx_c + p );
644  }
645 
646  if( end.y == 0 )
647  corner = wxPoint( end.x, w / 2 );
648  else
649  corner = wxPoint( -( w / 2 ), end.y );
650 
651  RotatePoint( &end, aPad->GetOrientation() );
652  RotatePoint( &corner, aPad->GetOrientation() );
653  shape->Append( wx_c + corner );
654 
655  for( int rot = 100; rot <= 1800; rot += 100 )
656  {
657  wxPoint p( corner );
658  RotatePoint( &p, end, rot );
659  shape->Append( wx_c + p );
660  }
661 
662  solid->SetShape( shape );
663  }
664  break;
665 
666  case PAD_SHAPE_RECT:
667  case PAD_SHAPE_TRAPEZOID:
668  {
669  wxPoint coords[4];
670  aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
671 
672  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
673  for( int ii = 0; ii < 4; ii++ )
674  {
675  shape->Append( wx_c + coords[ii] );
676  }
677 
678  solid->SetShape( shape );
679  break;
680  }
681 
682  case PAD_SHAPE_ROUNDRECT:
683  {
684  SHAPE_POLY_SET outline;
685  const int segmentToCircleCount = 32;
686  aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ),
687  segmentToCircleCount, 1.0 );
688 
689  // TransformRoundRectToPolygon creates only one convex polygon
690  SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
691  SHAPE_CONVEX* shape = new SHAPE_CONVEX();
692 
693  for( int ii = 0; ii < poly.PointCount(); ++ii )
694  {
695  shape->Append( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
696  }
697 
698  solid->SetShape( shape );
699  break;
700  }
701 
702  default:
703  wxLogTrace( "PNS", "unsupported pad shape" );
704  return nullptr;
705  }
706  }
707  }
708  return solid;
709 }
710 
711 
712 std::unique_ptr<PNS::SEGMENT> PNS_KICAD_IFACE::syncTrack( TRACK* aTrack )
713 {
714  std::unique_ptr< PNS::SEGMENT > segment(
715  new PNS::SEGMENT( SEG( aTrack->GetStart(), aTrack->GetEnd() ), aTrack->GetNetCode() )
716  );
717 
718  segment->SetWidth( aTrack->GetWidth() );
719  segment->SetLayers( LAYER_RANGE( aTrack->GetLayer() ) );
720  segment->SetParent( aTrack );
721 
722  if( aTrack->IsLocked() )
723  segment->Mark( PNS::MK_LOCKED );
724 
725  return segment;
726 }
727 
728 
729 std::unique_ptr<PNS::VIA> PNS_KICAD_IFACE::syncVia( VIA* aVia )
730 {
731  PCB_LAYER_ID top, bottom;
732  aVia->LayerPair( &top, &bottom );
733  std::unique_ptr<PNS::VIA> via( new PNS::VIA(
734  aVia->GetPosition(),
735  LAYER_RANGE( top, bottom ),
736  aVia->GetWidth(),
737  aVia->GetDrillValue(),
738  aVia->GetNetCode(),
739  aVia->GetViaType() )
740  );
741 
742  via->SetParent( aVia );
743 
744  if( aVia->IsLocked() )
745  via->Mark( PNS::MK_LOCKED );
746 
747  return via;
748 }
749 
750 
752 {
753  m_board = aBoard;
754  wxLogTrace( "PNS", "m_board = %p", m_board );
755 }
756 
757 
759 {
760  if( !m_board )
761  {
762  wxLogTrace( "PNS", "No board attached, aborting sync." );
763  return;
764  }
765 
766  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
767  {
768  for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
769  {
770  std::unique_ptr< PNS::SOLID > solid = syncPad( pad );
771 
772  if( solid )
773  aWorld->Add( std::move( solid ) );
774  }
775  }
776 
777  for( TRACK* t = m_board->m_Track; t; t = t->Next() )
778  {
779  KICAD_T type = t->Type();
780 
781  if( type == PCB_TRACE_T ) {
782  std::unique_ptr< PNS::SEGMENT > segment = syncTrack( t );
783  if( segment ) {
784  aWorld->Add( std::move( segment ) );
785  }
786  } else if( type == PCB_VIA_T ) {
787  std::unique_ptr< PNS::VIA > via = syncVia( static_cast<VIA*>( t ) );
788  if( via ) {
789  aWorld->Add( std::move( via ) );
790  }
791  }
792  }
793 
794  int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue();
795 
796  delete m_ruleResolver;
798 
799  aWorld->SetRuleResolver( m_ruleResolver );
800  aWorld->SetMaxClearance( 4 * worstClearance );
801 }
802 
803 
805 {
806  for( auto item : m_hiddenItems )
807  m_view->SetVisible( item, true );
808 
809  m_hiddenItems.clear();
810 
811  if( m_previewItems )
812  {
815  }
816 
817  if( m_debugDecorator )
819 }
820 
821 
822 void PNS_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aColor, int aClearance )
823 {
824  wxLogTrace( "PNS", "DisplayItem %p", aItem );
825 
826  ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_view );
827 
828  if( aColor >= 0 )
829  pitem->SetColor( KIGFX::COLOR4D( aColor ) );
830 
831  if( aClearance >= 0 )
832  {
833  pitem->SetClearance( aClearance );
834 
835  if( m_dispOptions )
836  {
837  auto clearanceDisp = m_dispOptions->m_ShowTrackClearanceMode;
838  pitem->ShowTrackClearance( clearanceDisp != DO_NOT_SHOW_CLEARANCE );
839  pitem->ShowViaClearance( clearanceDisp != DO_NOT_SHOW_CLEARANCE
840  && clearanceDisp != SHOW_CLEARANCE_NEW_TRACKS );
841  }
842  }
843 
844 
845  m_previewItems->Add( pitem );
847 }
848 
849 
851 {
852  BOARD_CONNECTED_ITEM* parent = aItem->Parent();
853 
854  if( parent )
855  {
856  if( m_view->IsVisible( parent ) )
857  m_hiddenItems.insert( parent );
858 
859  m_view->SetVisible( parent, false );
860  m_view->Update( parent, KIGFX::APPEARANCE );
861  }
862 }
863 
864 
866 {
867  BOARD_CONNECTED_ITEM* parent = aItem->Parent();
868 
869  if( parent )
870  {
871  m_commit->Remove( parent );
872  }
873 }
874 
875 
877 {
878  BOARD_CONNECTED_ITEM* newBI = NULL;
879 
880  switch( aItem->Kind() )
881  {
883  {
884  PNS::SEGMENT* seg = static_cast<PNS::SEGMENT*>( aItem );
885  TRACK* track = new TRACK( m_board );
886  const SEG& s = seg->Seg();
887  track->SetStart( wxPoint( s.A.x, s.A.y ) );
888  track->SetEnd( wxPoint( s.B.x, s.B.y ) );
889  track->SetWidth( seg->Width() );
890  track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) );
891  track->SetNetCode( seg->Net() > 0 ? seg->Net() : 0 );
892  newBI = track;
893  break;
894  }
895 
896  case PNS::ITEM::VIA_T:
897  {
898  VIA* via_board = new VIA( m_board );
899  PNS::VIA* via = static_cast<PNS::VIA*>( aItem );
900  via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) );
901  via_board->SetWidth( via->Diameter() );
902  via_board->SetDrill( via->Drill() );
903  via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 );
904  via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair()
905  via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ),
906  ToLAYER_ID( via->Layers().End() ) );
907  newBI = via_board;
908  break;
909  }
910 
911  default:
912  break;
913  }
914 
915  if( newBI )
916  {
917  aItem->SetParent( newBI );
918  newBI->ClearFlags();
919 
920  m_commit->Add( newBI );
921  }
922 }
923 
924 
926 {
927  EraseView();
928  m_commit->Push( wxT( "Added a track" ) );
929  m_commit.reset( new BOARD_COMMIT( m_frame ) );
930 }
931 
932 
934 {
935  wxLogTrace( "PNS", "SetView %p", aView );
936 
937  if( m_previewItems )
938  {
940  delete m_previewItems;
941  }
942 
943  m_view = aView;
947 
948  delete m_debugDecorator;
951 }
952 
953 
954 void PNS_KICAD_IFACE::UpdateNet( int aNetCode )
955 {
956  wxLogTrace( "PNS", "Update-net %d", aNetCode );
957 }
958 
959 
961 {
962  return m_ruleResolver;
963 }
964 
965 
967 {
968  m_router = aRouter;
969 }
970 
971 
973 {
974  m_frame = aFrame;
975 
976  m_commit.reset( new BOARD_COMMIT( m_frame ) );
978 }
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:440
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:412
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.
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:439
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:533
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
void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1385
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
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.
Definition: class_netinfo.h:69
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:169
DLIST< MODULE > m_Modules
Definition: class_board.h:245
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:447
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:411
wxPoint ShapePos() const
Definition: class_pad.cpp:418
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:254
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
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:246
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
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:786
#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