KiCad PCB EDA Suite
board_netlist_updater.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
10  * Copyright (C) 2015 CERN
11  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
12  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
13  *
14  * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, you may find one here:
28  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
29  * or you may search the http://www.gnu.org website for the version 2 license,
30  * or you may write to the Free Software Foundation, Inc.,
31  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
32  */
33 
34 
35 #include <common.h> // for PAGE_INFO
36 
37 #include <class_board.h>
38 #include <netinfo.h>
39 #include <class_module.h>
40 #include <class_pad.h>
41 #include <class_track.h>
42 #include <class_zone.h>
43 
44 #include "pcb_netlist.h"
46 #include <reporter.h>
47 
48 #include "board_netlist_updater.h"
49 
50 #include <pcb_edit_frame.h>
51 
52 
54  m_frame( aFrame ),
55  m_commit( aFrame ),
56  m_board( aBoard )
57 {
59 
60  m_deleteSinglePadNets = true;
62  m_isDryRun = false;
63  m_replaceFootprints = true;
64  m_lookupByTimestamp = false;
65  m_warnForNoNetPads = false;
66 
67  m_warningCount = 0;
68  m_errorCount = 0;
70 }
71 
72 
74 {
75 }
76 
77 
78 // These functions allow inspection of pad nets during dry runs by keeping a cache of
79 // current pad netnames indexed by pad.
80 
81 void BOARD_NETLIST_UPDATER::cacheNetname( D_PAD* aPad, const wxString& aNetname )
82 {
83  m_padNets[ aPad ] = aNetname;
84 }
85 
86 
88 {
89  if( m_isDryRun && m_padNets.count( aPad ) )
90  return m_padNets[ aPad ];
91  else
92  return aPad->GetNetname();
93 }
94 
95 
96 void BOARD_NETLIST_UPDATER::cachePinFunction( D_PAD* aPad, const wxString& aPinFunction )
97 {
98  m_padPinFunctions[ aPad ] = aPinFunction;
99 }
100 
101 
103 {
104  if( m_isDryRun && m_padPinFunctions.count( aPad ) )
105  return m_padPinFunctions[ aPad ];
106  else
107  return aPad->GetPinFunction();
108 }
109 
110 
112 {
113  wxPoint bestPosition;
114 
115  if( !m_board->IsEmpty() )
116  {
117  // Position new components below any existing board features.
119 
120  if( bbox.GetWidth() || bbox.GetHeight() )
121  {
122  bestPosition.x = bbox.Centre().x;
123  bestPosition.y = bbox.GetBottom() + Millimeter2iu( 10 );
124  }
125  }
126  else
127  {
128  // Position new components in the center of the page when the board is empty.
129  wxSize pageSize = m_board->GetPageSettings().GetSizeIU();
130 
131  bestPosition.x = pageSize.GetWidth() / 2;
132  bestPosition.y = pageSize.GetHeight() / 2;
133  }
134 
135  return bestPosition;
136 }
137 
138 
140 {
141  wxString msg;
142 
143  if( aComponent->GetFPID().empty() )
144  {
145  msg.Printf( _( "Cannot add %s (no footprint assigned)." ),
146  aComponent->GetReference(),
147  aComponent->GetFPID().Format().wx_str() );
149  ++m_errorCount;
150  return nullptr;
151  }
152 
153  MODULE* footprint = m_frame->LoadFootprint( aComponent->GetFPID() );
154 
155  if( footprint == nullptr )
156  {
157  msg.Printf( _( "Cannot add %s (footprint \"%s\" not found)." ),
158  aComponent->GetReference(),
159  aComponent->GetFPID().Format().wx_str() );
161  ++m_errorCount;
162  return nullptr;
163  }
164 
165  msg.Printf( _( "Add %s (footprint \"%s\")." ),
166  aComponent->GetReference(),
167  aComponent->GetFPID().Format().wx_str() );
169 
170  // Set the pads ratsnest settings to the global settings
171  bool set_ratsnest = m_frame->GetDisplayOptions().m_ShowGlobalRatsnest;
172  for ( auto pad : footprint->Pads() )
173  pad->SetLocalRatsnestVisible( set_ratsnest );
174 
176 
177  if( !m_isDryRun )
178  {
179  footprint->SetParent( m_board );
181 
182  m_addedComponents.push_back( footprint );
183  m_commit.Add( footprint );
184 
185  return footprint;
186  }
187  else
188  delete footprint;
189 
190  return NULL;
191 }
192 
193 
195  COMPONENT* aNewComponent )
196 {
197  wxString msg;
198 
199  if( aNewComponent->GetFPID().empty() )
200  {
201  msg.Printf( _( "Cannot update %s (no footprint assigned)." ),
202  aNewComponent->GetReference(),
203  aNewComponent->GetFPID().Format().wx_str() );
205  ++m_errorCount;
206  return nullptr;
207  }
208 
209  MODULE* newFootprint = m_frame->LoadFootprint( aNewComponent->GetFPID() );
210 
211  if( newFootprint == nullptr )
212  {
213  msg.Printf( _( "Cannot update %s (footprint \"%s\" not found)." ),
214  aNewComponent->GetReference(),
215  aNewComponent->GetFPID().Format().wx_str() );
217  ++m_errorCount;
218  return nullptr;
219  }
220 
221  msg.Printf( _( "Change %s footprint from \"%s\" to \"%s\"."),
222  aPcbComponent->GetReference(),
223  aPcbComponent->GetFPID().Format().wx_str(),
224  aNewComponent->GetFPID().Format().wx_str() );
226 
228 
229  if( !m_isDryRun )
230  {
231  m_frame->Exchange_Module( aPcbComponent, newFootprint, m_commit );
232  return newFootprint;
233  }
234  else
235  delete newFootprint;
236 
237  return nullptr;
238 }
239 
240 
242  COMPONENT* aNewComponent )
243 {
244  wxString msg;
245 
246  // Create a copy only if the module has not been added during this update
247  MODULE* copy = m_commit.GetStatus( aPcbComponent ) ? nullptr : (MODULE*) aPcbComponent->Clone();
248  bool changed = false;
249 
250  // Test for reference designator field change.
251  if( aPcbComponent->GetReference() != aNewComponent->GetReference() )
252  {
253  msg.Printf( _( "Change %s reference designator to %s." ),
254  aPcbComponent->GetReference(),
255  aNewComponent->GetReference() );
257 
258  if ( !m_isDryRun )
259  {
260  changed = true;
261  aPcbComponent->SetReference( aNewComponent->GetReference() );
262  }
263  }
264 
265  // Test for value field change.
266  if( aPcbComponent->GetValue() != aNewComponent->GetValue() )
267  {
268  msg.Printf( _( "Change %s value from %s to %s." ),
269  aPcbComponent->GetReference(),
270  aPcbComponent->GetValue(),
271  aNewComponent->GetValue() );
273 
274  if( !m_isDryRun )
275  {
276  changed = true;
277  aPcbComponent->SetValue( aNewComponent->GetValue() );
278  }
279  }
280 
281  // Test for time stamp change.
282  if( aPcbComponent->GetPath() != aNewComponent->GetPath() )
283  {
284  msg.Printf( _( "Update %s symbol association from %s to %s." ),
285  aPcbComponent->GetReference(),
286  aPcbComponent->GetPath().AsString(),
287  aNewComponent->GetPath().AsString() );
289 
290  if( !m_isDryRun )
291  {
292  changed = true;
293  aPcbComponent->SetPath( aNewComponent->GetPath() );
294  }
295  }
296 
297  if( aPcbComponent->GetProperties() != aNewComponent->GetProperties() )
298  {
299  msg.Printf( _( "Update %s properties." ),
300  aPcbComponent->GetReference() );
302 
303  if( !m_isDryRun )
304  {
305  changed = true;
306  aPcbComponent->SetProperties( aNewComponent->GetProperties() );
307  }
308  }
309 
310  if( changed && copy )
311  m_commit.Modified( aPcbComponent, copy );
312  else
313  delete copy;
314 
315  return true;
316 }
317 
318 
320  COMPONENT* aNewComponent )
321 {
322  wxString msg;
323 
324  // Create a copy only if the module has not been added during this update
325  MODULE* copy = m_commit.GetStatus( aPcbComponent ) ? nullptr : (MODULE*) aPcbComponent->Clone();
326  bool changed = false;
327 
328  // At this point, the component footprint is updated. Now update the nets.
329  for( auto pad : aPcbComponent->Pads() )
330  {
331  const COMPONENT_NET& net = aNewComponent->GetNet( pad->GetName() );
332 
333  wxString pinFunction;
334 
335  if( net.IsValid() ) // i.e. the pad has a name
336  pinFunction = net.GetPinFunction();
337 
338  if( !m_isDryRun )
339  {
340  if( pad->GetPinFunction() != pinFunction )
341  {
342  changed = true;
343  pad->SetPinFunction( pinFunction );
344  }
345  }
346  else
347  cachePinFunction( pad, pinFunction );
348 
349  // Test if new footprint pad has no net (pads not on copper layers have no net).
350  if( !net.IsValid() || !pad->IsOnCopperLayer() )
351  {
352  if( !pad->GetNetname().IsEmpty() )
353  {
354  msg.Printf( _( "Disconnect %s pin %s." ),
355  aPcbComponent->GetReference(),
356  pad->GetName() );
358  }
359  else if( m_warnForNoNetPads && pad->IsOnCopperLayer() && !pad->GetName().IsEmpty() )
360  {
361  // pad is connectable but has no net found in netlist
362  msg.Printf( _( "No net for component %s pin %s." ),
363  aPcbComponent->GetReference(),
364  pad->GetName() );
366  }
367 
368  if( !m_isDryRun )
369  {
370  changed = true;
371  pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
372 
373  // If the pad has no net from netlist (i.e. not in netlist
374  // it cannot have a pin function
375  if( pad->GetNetname().IsEmpty() )
376  pad->SetPinFunction( wxEmptyString );
377 
378  }
379  else
380  cacheNetname( pad, wxEmptyString );
381  }
382  else // New footprint pad has a net.
383  {
384  const wxString& netName = net.GetNetName();
385  NETINFO_ITEM* netinfo = m_board->FindNet( netName );
386 
387  if( netinfo && !m_isDryRun )
388  netinfo->SetIsCurrent( true );
389 
390  if( pad->GetNetname() != netName )
391  {
392 
393  if( netinfo == nullptr )
394  {
395  // It might be a new net that has not been added to the board yet
396  if( m_addedNets.count( netName ) )
397  netinfo = m_addedNets[ netName ];
398  }
399 
400  if( netinfo == nullptr )
401  {
402  netinfo = new NETINFO_ITEM( m_board, netName );
403 
404  // It is a new net, we have to add it
405  if( !m_isDryRun )
406  {
407  changed = true;
408  m_commit.Add( netinfo );
409  }
410 
411  m_addedNets[netName] = netinfo;
412  msg.Printf( _( "Add net %s." ), UnescapeString( netName ) );
414  }
415 
416  if( !pad->GetNetname().IsEmpty() )
417  {
418  m_oldToNewNets[ pad->GetNetname() ] = netName;
419 
420  msg.Printf( _( "Reconnect %s pin %s from %s to %s."),
421  aPcbComponent->GetReference(),
422  pad->GetName(),
423  UnescapeString( pad->GetNetname() ),
424  UnescapeString( netName ) );
425  }
426  else
427  {
428  msg.Printf( _( "Connect %s pin %s to %s."),
429  aPcbComponent->GetReference(),
430  pad->GetName(),
431  UnescapeString( netName ) );
432  }
434 
435  if( !m_isDryRun )
436  {
437  changed = true;
438  pad->SetNet( netinfo );
439  }
440  else
441  cacheNetname( pad, netName );
442  }
443  }
444  }
445 
446  if( changed && copy )
447  m_commit.Modified( aPcbComponent, copy );
448  else
449  delete copy;
450 
451  return true;
452 }
453 
454 
456 {
457  for( int ii = 0; ii < m_board->GetAreaCount(); ii++ )
458  {
459  ZONE_CONTAINER* zone = m_board->GetArea( ii );
460 
461  if( !zone->IsOnCopperLayer() || zone->GetIsKeepout() )
462  continue;
463 
464  m_zoneConnectionsCache[ zone ] = m_board->GetConnectivity()->GetConnectedPads( zone );
465  }
466 }
467 
468 
470 {
471  wxString msg;
472  std::set<wxString> netlistNetnames;
473 
474  for( int ii = 0; ii < (int) aNetlist.GetCount(); ii++ )
475  {
476  const COMPONENT* component = aNetlist.GetComponent( ii );
477  for( unsigned jj = 0; jj < component->GetNetCount(); jj++ )
478  {
479  const COMPONENT_NET& net = component->GetNet( jj );
480  netlistNetnames.insert( net.GetNetName() );
481  }
482  }
483 
484  for( auto via : m_board->Tracks() )
485  {
486  if( via->Type() != PCB_VIA_T )
487  continue;
488 
489  if( netlistNetnames.count( via->GetNetname() ) == 0 )
490  {
491  wxString updatedNetname = wxEmptyString;
492 
493  // Take via name from name change map if it didn't match to a new pad
494  // (this is useful for stitching vias that don't connect to tracks)
495  if( m_oldToNewNets.count( via->GetNetname() ) )
496  {
497  updatedNetname = m_oldToNewNets[via->GetNetname()];
498  }
499 
500  if( !updatedNetname.IsEmpty() )
501  {
502  msg.Printf( _( "Reconnect via from %s to %s." ),
503  UnescapeString( via->GetNetname() ), UnescapeString( updatedNetname ) );
505 
506  if( !m_isDryRun )
507  {
508  NETINFO_ITEM* netinfo = m_board->FindNet( updatedNetname );
509 
510  if( !netinfo )
511  netinfo = m_addedNets[updatedNetname];
512 
513  if( netinfo )
514  {
515  m_commit.Modify( via );
516  via->SetNet( netinfo );
517  }
518  }
519  }
520  else
521  {
522  msg.Printf( _( "Via connected to unknown net (%s)." ),
523  UnescapeString( via->GetNetname() ) );
525  ++m_warningCount;
526  }
527  }
528  }
529 
530  // Test copper zones to detect "dead" nets (nets without any pad):
531  for( int i = 0; i < m_board->GetAreaCount(); i++ )
532  {
533  ZONE_CONTAINER* zone = m_board->GetArea( i );
534 
535  if( !zone->IsOnCopperLayer() || zone->GetIsKeepout() )
536  continue;
537 
538  if( netlistNetnames.count( zone->GetNetname() ) == 0 )
539  {
540  // Look for a pad in the zone's connected-pad-cache which has been updated to
541  // a new net and use that. While this won't always be the right net, the dead
542  // net is guaranteed to be wrong.
543  wxString updatedNetname = wxEmptyString;
544 
545  for( D_PAD* pad : m_zoneConnectionsCache[ zone ] )
546  {
547  if( getNetname( pad ) != zone->GetNetname() )
548  {
549  updatedNetname = getNetname( pad );
550  break;
551  }
552  }
553 
554  // Take zone name from name change map if it didn't match to a new pad
555  // (this is useful for zones on internal layers)
556  if( updatedNetname.IsEmpty() && m_oldToNewNets.count( zone->GetNetname() ) )
557  {
558  updatedNetname = m_oldToNewNets[ zone->GetNetname() ];
559  }
560 
561  if( !updatedNetname.IsEmpty() )
562  {
563  msg.Printf( _( "Reconnect copper zone from %s to %s." ),
564  UnescapeString( zone->GetNetname() ),
565  UnescapeString( updatedNetname ) );
567 
568  if( !m_isDryRun )
569  {
570  NETINFO_ITEM* netinfo = m_board->FindNet( updatedNetname );
571 
572  if( !netinfo )
573  netinfo = m_addedNets[ updatedNetname ];
574 
575  if( netinfo )
576  {
577  m_commit.Modify( zone );
578  zone->SetNet( netinfo );
579  }
580  }
581  }
582  else
583  {
584  msg.Printf( _( "Copper zone (%s) has no pads connected." ),
585  UnescapeString( zone->GetNetname() ) );
587  ++m_warningCount;
588  }
589  }
590  }
591 
592  return true;
593 }
594 
595 
597 {
598  wxString msg;
599  const COMPONENT* component;
600 
601  for( auto module : m_board->Modules() )
602  {
603 
604  if( m_lookupByTimestamp )
605  component = aNetlist.GetComponentByPath( module->GetPath() );
606  else
607  component = aNetlist.GetComponentByReference( module->GetReference() );
608 
609  if( component == NULL )
610  {
611  if( module->IsLocked() )
612  {
613  msg.Printf( _( "Cannot remove unused footprint %s (locked)." ), module->GetReference() );
615  continue;
616  }
617 
618  msg.Printf( _( "Remove unused footprint %s." ), module->GetReference() );
620 
621  if( !m_isDryRun )
622  m_commit.Remove( module );
623  }
624  }
625 
626  return true;
627 }
628 
629 
631 {
632  int count = 0;
633  wxString netname;
634  wxString msg;
635  D_PAD* previouspad = NULL;
636 
637  // We need the pad list for next tests.
638 
640 
641  std::vector<D_PAD*> padlist = m_board->GetPads();
642 
643  // Sort pads by netlist name
644  std::sort( padlist.begin(), padlist.end(),
645  [ this ]( D_PAD* a, D_PAD* b ) -> bool { return getNetname( a ) < getNetname( b ); } );
646 
647  for( D_PAD* pad : padlist )
648  {
649  if( getNetname( pad ).IsEmpty() )
650  continue;
651 
652  if( netname != getNetname( pad ) ) // End of net
653  {
654  if( previouspad && count == 1 )
655  {
656  // First, see if we have a copper zone attached to this pad.
657  // If so, this is not really a single pad net
658 
659  for( ZONE_CONTAINER* zone : m_board->Zones() )
660  {
661  if( !zone->IsOnCopperLayer() )
662  continue;
663 
664  if( zone->GetIsKeepout() )
665  continue;
666 
667  if( zone->GetNetname() == getNetname( previouspad ) )
668  {
669  count++;
670  break;
671  }
672  }
673 
674  if( count == 1 ) // Really one pad, and nothing else
675  {
676  msg.Printf( _( "Remove single pad net %s." ),
677  UnescapeString( getNetname( previouspad ) ) );
679 
680  if( !m_isDryRun )
681  previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
682  else
683  cacheNetname( previouspad, wxEmptyString );
684  }
685  }
686 
687  netname = getNetname( pad );
688  count = 1;
689  }
690  else
691  {
692  count++;
693  }
694 
695  previouspad = pad;
696  }
697 
698  // Examine last pad
699  if( count == 1 )
700  {
701  if( !m_isDryRun )
702  previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
703  else
704  cacheNetname( previouspad, wxEmptyString );
705  }
706 
707  return true;
708 }
709 
710 
712 {
713  // Verify that board contains all pads in netlist: if it doesn't then footprints are
714  // wrong or missing.
715  // Note that we use references to find the footprints as they're already updated by this
716  // point (whether by-reference or by-timestamp).
717 
718  wxString msg;
719  wxString padname;
720 
721  for( int i = 0; i < (int) aNetlist.GetCount(); i++ )
722  {
723  const COMPONENT* component = aNetlist.GetComponent( i );
724  MODULE* footprint = m_board->FindModuleByReference( component->GetReference() );
725 
726  if( footprint == NULL ) // It can be missing in partial designs
727  continue;
728 
729  // Explore all pins/pads in component
730  for( unsigned jj = 0; jj < component->GetNetCount(); jj++ )
731  {
732  const COMPONENT_NET& net = component->GetNet( jj );
733  padname = net.GetPinName();
734 
735  if( footprint->FindPadByName( padname ) )
736  continue; // OK, pad found
737 
738  // not found: bad footprint, report error
739  msg.Printf( _( "%s pad %s not found in %s." ),
740  component->GetReference(),
741  padname,
742  footprint->GetFPID().Format().wx_str() );
744  ++m_errorCount;
745  }
746  }
747 
748  return true;
749 }
750 
751 
753 {
754  wxString msg;
755  m_errorCount = 0;
756  m_warningCount = 0;
758  MODULE* lastPreexistingFootprint = m_board->Modules().empty() ? NULL : m_board->Modules().back();
759 
761 
762  if( !m_isDryRun )
763  {
764  m_board->SetStatus( 0 );
765 
766  // Mark all nets (except <no net>) as stale; we'll update those to current that
767  // we find in the netlist
768  for( NETINFO_ITEM* net : m_board->GetNetInfo() )
769  net->SetIsCurrent( net->GetNet() == 0 );
770  }
771 
772  for( unsigned i = 0; i < aNetlist.GetCount(); i++ )
773  {
774  COMPONENT* component = aNetlist.GetComponent( i );
775  int matchCount = 0;
776  MODULE* tmp;
777 
778  msg.Printf( _( "Processing component \"%s:%s\"." ),
779  component->GetReference(),
780  component->GetFPID().Format().wx_str() );
782 
783  for( auto footprint : m_board->Modules() )
784  {
785  bool match = false;
786 
787  if( footprint )
788  {
789  if( m_lookupByTimestamp )
790  match = footprint->GetPath() == component->GetPath();
791  else
792  match = footprint->GetReference().CmpNoCase( component->GetReference() ) == 0;
793  }
794 
795  if( match )
796  {
797  tmp = footprint;
798 
799  if( m_replaceFootprints && component->GetFPID() != footprint->GetFPID() )
800  tmp = replaceComponent( aNetlist, footprint, component );
801 
802  if( tmp )
803  {
804  updateComponentParameters( tmp, component );
805  updateComponentPadConnections( tmp, component );
806  }
807 
808  matchCount++;
809  }
810 
811  if( footprint == lastPreexistingFootprint )
812  {
813  // No sense going through the newly-created footprints: end of loop
814  break;
815  }
816  }
817 
818  if( matchCount == 0 )
819  {
820  tmp = addNewComponent( component );
821 
822  if( tmp )
823  {
824  updateComponentParameters( tmp, component );
825  updateComponentPadConnections( tmp, component );
826  }
827  }
828  else if( matchCount > 1 )
829  {
830  msg.Printf( _( "Multiple footprints found for \"%s\"." ),
831  component->GetReference() );
833  }
834  }
835 
836  updateCopperZoneNets( aNetlist );
837 
839  deleteUnusedComponents( aNetlist );
840 
841  if( !m_isDryRun )
842  {
843  m_board->GetConnectivity()->Build( m_board );
844  testConnectivity( aNetlist );
845 
846  // Now the connectivity data is rebuilt, we can delete single pads nets
849 
850  for( NETINFO_ITEM* net : m_board->GetNetInfo() )
851  {
852  if( !net->IsCurrent() )
853  {
854  msg.Printf( _( "Remove unused net \"%s\"." ), net->GetNetname() );
856  m_commit.Removed( net );
857  }
858  }
859 
861  m_commit.Push( _( "Update netlist" ) );
862  }
864  // We can delete single net pads in dry run mode only if no new footprints
865  // are added, because these new footprints are not actually added to the board
866  // and the current pad list is wrong in this case.
868 
869  if( m_isDryRun )
870  {
871  for( const auto& it : m_addedNets )
872  delete it.second;
873 
874  m_addedNets.clear();
875  }
876 
877  // Update the ratsnest
880 
881  msg.Printf( _( "Total warnings: %d, errors: %d." ), m_warningCount, m_errorCount );
883 
884  if( m_errorCount )
885  {
886  m_reporter->ReportTail( _( "Errors occurred during the netlist update. Unless you fix them "
887  "your board will not be consistent with the schematics." ),
889  return false;
890  }
891 
892  return true;
893 }
NETINFO_ITEM * FindNet(int aNetcode) const
Function FindNet searches for a net with the given netcode.
void BuildListOfNets()
Definition: class_board.h:720
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:61
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
MODULE * replaceComponent(NETLIST &aNetlist, MODULE *aPcbComponent, COMPONENT *aNewComponent)
const PAGE_INFO & GetPageSettings() const
Definition: class_board.h:574
COMPONENT * GetComponentByPath(const KIID_PATH &aPath)
Function GetComponentByPath returns a COMPONENT by aPath.
void cacheNetname(D_PAD *aPad, const wxString &aNetname)
COMMIT & Add(EDA_ITEM *aItem)
Adds a new item to the model
Definition: commit.h:78
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:800
void SetIsCurrent(bool isCurrent)
Definition: netinfo.h:256
std::map< ZONE_CONTAINER *, std::vector< D_PAD * > > m_zoneConnectionsCache
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportTail Places the report at the end of the list, for objects that support report orderin...
Definition: reporter.h:94
int GetWidth() const
Definition: eda_rect.h:119
PADS & Pads()
Definition: class_module.h:173
const wxString GetValue() const
Function GetValue.
Definition: class_module.h:469
bool SetNetCode(int aNetCode, bool aNoAssert)
Sets net using a net code.
BOARD_NETLIST_UPDATER class definition.
unsigned GetCount() const
Function GetCount.
Definition: pcb_netlist.h:236
int GetStatus(EDA_ITEM *aItem)
Returns status of an item.
Definition: commit.cpp:132
const NETINFO_LIST & GetNetInfo() const
Definition: class_board.h:741
const LIB_ID & GetFPID() const
Definition: class_module.h:225
bool updateComponentPadConnections(MODULE *aPcbComponent, COMPONENT *aNewComponent)
bool updateCopperZoneNets(NETLIST &aNetlist)
const KIID_PATH & GetPath() const
Definition: class_module.h:234
bool testConnectivity(NETLIST &aNetlist)
void Exchange_Module(MODULE *aSrc, MODULE *aDest, BOARD_COMMIT &aCommit, bool deleteExtraTexts=true, bool resetTextLayers=true, bool resetTextEffects=true, bool reset3DModels=true)
Function Exchange_Module Replaces OldModule by NewModule, using OldModule settings: position,...
const wxString & GetPinFunction() const
Definition: class_pad.h:138
void RemoveUnusedNets()
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Function GetDisplayOptions Display options control the way tracks, vias, outlines and other things ar...
bool UpdateNetlist(NETLIST &aNetlist)
Function UpdateNetlist()
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
bool empty() const
Definition: lib_id.h:186
virtual void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:196
A single base class (TRACK) represents both tracks and vias, with subclasses for curved tracks (ARC) ...
int GetBottom() const
Definition: eda_rect.h:124
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:444
std::map< wxString, NETINFO_ITEM * > m_addedNets
const LIB_ID & GetFPID() const
Definition: pcb_netlist.h:157
COMPONENT_NET is used to store the component pin name to net name (and pin function) associations sto...
Definition: pcb_netlist.h:44
COMMIT & Removed(EDA_ITEM *aItem)
Notifies observers that aItem has been removed
Definition: commit.h:96
D_PAD * FindPadByName(const wxString &aPadName) const
Function FindPadByName returns a D_PAD* with a matching name.
const wxString & GetNetName() const
Definition: pcb_netlist.h:60
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:934
NETLIST stores all of information read from a netlist along with the flags used to update the NETLIST...
Definition: pcb_netlist.h:194
#define NULL
wxString getNetname(D_PAD *aPad)
MODULES & Modules()
Definition: class_board.h:266
wxString getPinFunction(D_PAD *aPad)
unsigned GetNetCount() const
Definition: pcb_netlist.h:133
const wxString & GetReference() const
Definition: pcb_netlist.h:147
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:355
std::map< wxString, wxString > m_oldToNewNets
void SetReference(const wxString &aReference)
Function SetReference.
Definition: class_module.h:454
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
COMMIT & Remove(EDA_ITEM *aItem)
Removes a new item from the model
Definition: commit.h:90
void SetPosition(const wxPoint &aPos) override
const wxString & GetNetname() const
Function GetNetname.
const COMPONENT_NET & GetNet(unsigned aIndex) const
Definition: pcb_netlist.h:135
std::map< D_PAD *, wxString > m_padNets
int GetHeight() const
Definition: eda_rect.h:120
UTF8 Format() const
Definition: lib_id.cpp:237
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:712
Pad object description.
COMPONENT is used to store components and all of their related information found in a netlist.
Definition: pcb_netlist.h:80
const wxString & GetPinFunction() const
Definition: pcb_netlist.h:61
bool IsValid() const
Definition: pcb_netlist.h:63
COMPONENT * GetComponent(unsigned aIndex)
Function GetComponent returns the COMPONENT at aIndex.
Definition: pcb_netlist.h:245
void cachePinFunction(D_PAD *aPad, const wxString &aPinFunction)
COMMIT & Modified(EDA_ITEM *aItem, EDA_ITEM *aCopy)
Creates an undo entry for an item that has been already modified.
Definition: commit.h:110
const std::vector< D_PAD * > GetPads()
Function GetPads returns a reference to a list of all the pads.
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
ZONE_CONTAINERS & Zones()
Definition: class_board.h:280
MODULE * LoadFootprint(const LIB_ID &aFootprintId)
Function LoadFootprint attempts to load aFootprintId from the footprint library table.
bool updateComponentParameters(MODULE *aPcbComponent, COMPONENT *aNewComponent)
void SetProperties(const std::map< wxString, wxString > &aProps)
Definition: class_module.h:492
std::map< D_PAD *, wxString > m_padPinFunctions
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:180
#define _(s)
Definition: 3d_actions.cpp:33
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:125
wxString AsString() const
Definition: common.h:137
wxString wx_str() const
Definition: utf8.cpp:51
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
PCB_EDIT_FRAME is the main frame for Pcbnew.
void SetValue(const wxString &aValue)
Function SetValue.
Definition: class_module.h:478
The common library.
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
MODULE * FindModuleByReference(const wxString &aReference) const
Function FindModuleByReference searches for a MODULE within this board with the given reference desig...
void SetStatus(STATUS_FLAGS aStatus)
Definition: base_struct.h:230
wxPoint Centre() const
Definition: eda_rect.h:62
const wxString & GetPinName() const
Definition: pcb_netlist.h:59
const std::map< wxString, wxString > & GetProperties() const
Definition: class_module.h:491
const std::map< wxString, wxString > & GetProperties() const
Definition: pcb_netlist.h:154
const wxString & GetValue() const
Definition: pcb_netlist.h:148
COMPONENT * GetComponentByReference(const wxString &aReference)
Function GetComponentByReference returns a COMPONENT by aReference.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
std::vector< MODULE * > m_addedComponents
void SetPath(const KIID_PATH &aPath)
Definition: class_module.h:235
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:899
static REPORTER & GetInstance()
Definition: reporter.cpp:105
BOARD_NETLIST_UPDATER(PCB_EDIT_FRAME *aFrame, BOARD *aBoard)
const KIID_PATH & GetPath() const
Definition: pcb_netlist.h:162
bool deleteUnusedComponents(NETLIST &aNetlist)
static constexpr int Millimeter2iu(double mm)
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:478
bool IsEmpty() const
Definition: class_board.h:311
TRACKS & Tracks()
Definition: class_board.h:257
bool IsOnCopperLayer() const override
Function IsOnCopperLayer.
Definition: class_zone.cpp:218
MODULE * addNewComponent(COMPONENT *aComponent)