KiCad PCB EDA Suite
clean.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2004-2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
32 #include <fctsys.h>
33 #include <class_drawpanel.h>
34 #include <wxPcbStruct.h>
35 #include <pcbnew.h>
36 #include <class_board.h>
37 #include <class_track.h>
39 #include <board_commit.h>
40 #include <connectivity_data.h>
41 #include <connectivity_algo.h>
42 
43 // Helper class used to clean tracks and vias
45 {
46 public:
47  TRACKS_CLEANER( BOARD* aPcb, BOARD_COMMIT& aCommit );
48 
58  bool CleanupBoard( bool aCleanVias, bool aRemoveMisConnected,
59  bool aMergeSegments, bool aDeleteUnconnected );
60 
61 private:
62  /* finds and remove all track segments which are connected to more than one net.
63  * (short circuits)
64  */
66 
71  bool cleanupVias();
72 
77  void removeDuplicatesOfVia( const VIA *aVia, std::set<BOARD_ITEM *>& aToRemove );
78 
82  void removeDuplicatesOfTrack( const TRACK* aTrack, std::set<BOARD_ITEM*>& aToRemove );
83 
87  bool deleteDanglingTracks();
88 
90  bool deleteNullSegments();
91 
93  bool MergeCollinearTracks( TRACK* aSegment );
94 
98  bool cleanupSegments();
99 
106 
113  TRACK* aCandidate, ENDPOINT_T aEndType );
114 
115  const ZONE_CONTAINER* zoneForTrackEndpoint( const TRACK* aTrack,
116  ENDPOINT_T aEndPoint );
117 
118  bool testTrackEndpointDangling( TRACK* aTrack, ENDPOINT_T aEndPoint );
119 
122 
123  bool removeItems( std::set<BOARD_ITEM*>& aItems )
124  {
125  bool isModified = false;
126 
127 
128  for( auto item : aItems )
129  {
130  isModified = true;
131  m_brd->Remove( item );
132  m_commit.Removed( item );
133  }
134 
135  return isModified;
136  }
137 };
138 
139 
140 /* Install the cleanup dialog frame to know what should be cleaned
141 */
143 {
144  DIALOG_CLEANING_OPTIONS dlg( this );
145 
146  if( dlg.ShowModal() != wxID_OK )
147  return;
148 
149  // Old model has to be refreshed, GAL normally does not keep updating it
150  Compile_Ratsnest( NULL, false );
151 
152  wxBusyCursor( dummy );
153  BOARD_COMMIT commit( this );
154  TRACKS_CLEANER cleaner( GetBoard(), commit );
155 
156  bool modified = cleaner.CleanupBoard( dlg.m_deleteShortCircuits, dlg.m_cleanVias,
158 
159  if( modified )
160  {
161  // Clear undo and redo lists to avoid inconsistencies between lists
162  SetCurItem( NULL );
163  commit.Push( _( "Board cleanup" ) );
164  }
165 
166  m_canvas->Refresh( true );
167 }
168 
169 
171 {
172  auto connectivity = m_brd->GetConnectivity();
173 
174  connectivity->Build(m_brd);
175 
176  // clear flags and variables used in cleanup
177  for( auto track : m_brd->Tracks() )
178  {
179  track->SetState( START_ON_PAD | END_ON_PAD | BUSY, false );
180  }
181 
182  for( auto track : m_brd->Tracks() )
183  {
184  // Mark track if connected to pads
185  for( auto pad : connectivity->GetConnectedPads( track ) )
186  {
187  if( pad->HitTest( track->GetStart() ) )
188  {
189  track->SetState( START_ON_PAD, true );
190  }
191 
192  if( pad->HitTest( track->GetEnd() ) )
193  {
194  track->SetState( END_ON_PAD, true );
195  }
196  }
197  }
198 }
199 
200 
201 /* Main cleaning function.
202  * Delete
203  * - Redundant points on tracks (merge aligned segments)
204  * - vias on pad
205  * - null length segments
206  */
207 bool TRACKS_CLEANER::CleanupBoard( bool aRemoveMisConnected,
208  bool aCleanVias,
209  bool aMergeSegments,
210  bool aDeleteUnconnected )
211 {
212 
213  bool modified = false;
214 
215  // delete redundant vias
216  if( aCleanVias )
217  modified |= cleanupVias();
218 
219  // Remove null segments and intermediate points on aligned segments
220  // If not asked, remove null segments only if remove misconnected is asked
221  if( aMergeSegments )
222  modified |= cleanupSegments();
223  else if( aRemoveMisConnected )
224  modified |= deleteNullSegments();
225 
227 
228  if( aRemoveMisConnected )
229  modified |= removeBadTrackSegments();
230 
231  // Delete dangling tracks
232  if( aDeleteUnconnected )
233  {
235 
236  if( deleteDanglingTracks() )
237  {
238  modified = true;
239 
240  // Removed tracks can leave aligned segments
241  // (when a T was formed by tracks and the "vertical" segment
242  // is removed)
243  if( aMergeSegments )
244  cleanupSegments();
245  }
246  }
247 
248  return modified;
249 }
250 
251 
253  : m_brd( aPcb ), m_commit( aCommit )
254 {
255 
256 }
257 
258 
260 {
261  auto connectivity = m_brd->GetConnectivity();
262 
263  std::set<BOARD_ITEM *> toRemove;
264 
265  for( auto segment : m_brd->Tracks() )
266  {
267  segment->SetState( FLAG0, false );
268 
269  for( auto testedPad : connectivity->GetConnectedPads( segment ) )
270  {
271  if( segment->GetNetCode() != testedPad->GetNetCode() )
272  toRemove.insert( segment );
273  }
274 
275  for( auto testedTrack : connectivity->GetConnectedTracks( segment ) )
276  {
277  if( segment->GetNetCode() != testedTrack->GetNetCode() && !testedTrack->GetState( FLAG0 ) )
278  toRemove.insert( segment );
279  }
280  }
281 
282  return removeItems( toRemove );
283 }
284 
285 
286 void TRACKS_CLEANER::removeDuplicatesOfVia( const VIA *aVia, std::set<BOARD_ITEM *>& aToRemove )
287 {
288  VIA* next_via;
289 
290  for( VIA* alt_via = GetFirstVia( aVia->Next() ); alt_via != NULL; alt_via = next_via )
291  {
292  next_via = GetFirstVia( alt_via->Next() );
293 
294  if( ( alt_via->GetViaType() == VIA_THROUGH ) &&
295  ( alt_via->GetStart() == aVia->GetStart() ) )
296  aToRemove.insert ( alt_via );
297  }
298 }
299 
300 
302 {
303  std::set<BOARD_ITEM*> toRemove;
304 
305  for( VIA* via = GetFirstVia( m_brd->m_Track ); via != NULL;
306  via = GetFirstVia( via->Next() ) )
307  {
308  if( via->GetFlags() & TRACK_LOCKED )
309  continue;
310 
311  // Correct via m_End defects (if any), should never happen
312  if( via->GetStart() != via->GetEnd() )
313  {
314  wxFAIL_MSG( "Malformed via with mismatching ends" );
315  via->SetEnd( via->GetStart() );
316  }
317 
318  /* Important: these cleanups only do thru hole vias, they don't
319  * (yet) handle high density interconnects */
320  if( via->GetViaType() == VIA_THROUGH )
321  {
322  removeDuplicatesOfVia( via, toRemove );
323 
324  /* To delete through Via on THT pads at same location
325  * Examine the list of connected pads:
326  * if one through pad is found, the via can be removed */
327 
328  const auto pads = m_brd->GetConnectivity()->GetConnectedPads( via );
329  for( const auto pad : pads )
330  {
331  const LSET all_cu = LSET::AllCuMask();
332 
333  if( ( pad->GetLayerSet() & all_cu ) == all_cu )
334  {
335  // redundant: delete the via
336  toRemove.insert( via );
337  break;
338  }
339  }
340  }
341  }
342 
343  return removeItems( toRemove );
344 }
345 
346 
350 {
351  auto connectivity = m_brd->GetConnectivity();
352  VECTOR2I endpoint ;
353 
354  if( aTrack->Type() == PCB_TRACE_T )
355  endpoint = aTrack->GetEndPoint( aEndPoint );
356  else
357  endpoint = aTrack->GetStart( );
358 
359  //wxASSERT ( connectivity->GetConnectivityAlgo()->ItemEntry( aTrack ) != nullptr );
360  wxASSERT ( connectivity->GetConnectivityAlgo()->ItemEntry( aTrack ).GetItems().size() != 0 );
361  auto citem = connectivity->GetConnectivityAlgo()->ItemEntry( aTrack ).GetItems().front();
362 
363  if( !citem->Valid() )
364  return false;
365 
366  auto anchors = citem->Anchors();
367 
368  for( auto anchor : anchors )
369  {
370  if( anchor->Pos() == endpoint && anchor->IsDangling() )
371  return true;
372  }
373 
374  return false;
375 }
376 
377 
378 /* Delete dangling tracks
379  * Vias:
380  * If a via is only connected to a dangling track, it also will be removed
381  */
383 {
384  bool item_erased = false;
385  bool modified = false;
386 
387  do // Iterate when at least one track is deleted
388  {
389  item_erased = false;
390 
391  TRACK* next_track;
392 
393  for( TRACK *track = m_brd->m_Track; track != NULL; track = next_track )
394  {
395  next_track = track->Next();
396  bool flag_erase = false; // Start without a good reason to erase it
397 
398  /* if a track endpoint is not connected to a pad, test if
399  * the endpoint is connected to another track or to a zone.
400  * For via test, an enhancement could be to test if
401  * connected to 2 items on different layers. Currently
402  * a via must be connected to 2 items, that can be on the
403  * same layer */
404 
405  // Check if there is nothing attached on the start
406  if( !( track->GetState( START_ON_PAD ) ) )
407  flag_erase |= testTrackEndpointDangling( track, ENDPOINT_START );
408 
409  // If not sure about removal, then check if there is nothing attached on the end
410  if( !flag_erase && !track->GetState( END_ON_PAD ) )
411  flag_erase |= testTrackEndpointDangling( track, ENDPOINT_END );
412 
413  if( flag_erase )
414  {
415  m_brd->Remove( track );
416  m_commit.Removed( track );
417 
418  /* keep iterating, because a track connected to the deleted track
419  * now perhaps is not connected and should be deleted */
420  item_erased = true;
421  modified = true;
422  }
423  }
424  } while( item_erased );
425 
426 
427  return modified;
428 }
429 
430 
431 // Delete null length track segments
433 {
434  std::set<BOARD_ITEM *> toRemove;
435 
436  for( auto segment : m_brd->Tracks() )
437  {
438  if( segment->IsNull() ) // Length segment = 0; delete it
439  toRemove.insert( segment );
440  }
441 
442  return removeItems( toRemove );
443 }
444 
445 void TRACKS_CLEANER::removeDuplicatesOfTrack( const TRACK *aTrack, std::set<BOARD_ITEM*>& aToRemove )
446 {
447  if( aTrack->GetFlags() & STRUCT_DELETED )
448  return;
449 
450  for( auto other : m_brd->Tracks() )
451  {
452  // New netcode, break out (can't be there any other)
453  if( aTrack->GetNetCode() != other->GetNetCode() )
454  continue;
455 
456  if( aTrack == other )
457  continue;
458 
459  if( other->GetFlags() & STRUCT_DELETED )
460  continue;
461 
462  // Must be of the same type, on the same layer and the endpoints
463  // must be the same (maybe swapped)
464  if( ( aTrack->Type() == other->Type() ) &&
465  ( aTrack->GetLayer() == other->GetLayer() ) )
466  {
467  if( ( ( aTrack->GetStart() == other->GetStart() ) &&
468  ( aTrack->GetEnd() == other->GetEnd() ) ) ||
469  ( ( aTrack->GetStart() == other->GetEnd() ) &&
470  ( aTrack->GetEnd() == other->GetStart() ) ) )
471  {
472  other->SetFlags( STRUCT_DELETED );
473  aToRemove.insert( other );
474  }
475  }
476  }
477 }
478 
479 
481 {
482  bool merged_this = false;
483 
484 
485  for( ENDPOINT_T endpoint = ENDPOINT_START; endpoint <= ENDPOINT_END;
486  endpoint = ENDPOINT_T( endpoint + 1 ) )
487  {
488  // search for a possible segment connected to the current endpoint of the current one
489  TRACK* other = aSegment->Next();
490 
491  if( other )
492  {
493  other = aSegment->GetTrack( other, NULL, endpoint, true, false );
494 
495  if( other )
496  {
497  // the two segments must have the same width and the other
498  // cannot be a via
499  if( ( aSegment->GetWidth() == other->GetWidth() ) &&
500  ( other->Type() == PCB_TRACE_T ) )
501  {
502  // There can be only one segment connected
503  other->SetState( BUSY, true );
504  TRACK* yet_another = aSegment->GetTrack( m_brd->m_Track, NULL,
505  endpoint, true, false );
506  other->SetState( BUSY, false );
507 
508  if( !yet_another )
509  {
510  // Try to merge them
511  TRACK* segDelete = mergeCollinearSegmentIfPossible( aSegment,
512  other, endpoint );
513 
514  // Merge succesful, the other one has to go away
515  if( segDelete )
516  {
517  m_brd->Remove( segDelete );
518  m_commit.Removed( segDelete );
519  merged_this = true;
520  }
521  }
522  }
523  }
524  }
525  }
526 
527 
528 
529  return merged_this;
530 }
531 
532 
533 // Delete null length segments, and intermediate points ..
535 {
536  bool modified = false;
537 
538  // Easy things first
539  modified |= deleteNullSegments();
540 
542 
543  std::set<BOARD_ITEM*> toRemove;
544 
545  // Delete redundant segments, i.e. segments having the same end points and layers
546  // (can happens when blocks are copied on themselve)
547  for( auto segment : m_brd->Tracks() )
548  removeDuplicatesOfTrack( segment, toRemove );
549 
550  modified |= removeItems( toRemove );
551  modified = true;
552 
553  if( modified )
555 
556  // merge collinear segments:
557  TRACK* nextsegment;
558 
559  for( TRACK* segment = m_brd->m_Track; segment; segment = nextsegment )
560  {
561  nextsegment = segment->Next();
562 
563  if( segment->Type() == PCB_TRACE_T )
564  {
565  bool merged_this = MergeCollinearTracks( segment );
566 
567  if( merged_this ) // The current segment was modified, retry to merge it again
568  {
569  nextsegment = segment->Next();
570  modified = true;
571  }
572  }
573  }
574 
575  return modified;
576 }
577 
578 
579 /* Utility: check for parallelism between two segments */
580 static bool parallelismTest( int dx1, int dy1, int dx2, int dy2 )
581 {
582  /* The following condition list is ugly and repetitive, but I have
583  * not a better way to express clearly the trivial cases. Hope the
584  * compiler optimize it better than always doing the product
585  * below... */
586 
587  // test for vertical alignment (easy to handle)
588  if( dx1 == 0 )
589  return dx2 == 0;
590 
591  if( dx2 == 0 )
592  return dx1 == 0;
593 
594  // test for horizontal alignment (easy to handle)
595  if( dy1 == 0 )
596  return dy2 == 0;
597 
598  if( dy2 == 0 )
599  return dy1 == 0;
600 
601  /* test for alignment in other cases: Do the usual cross product test
602  * (the same as testing the slope, but without a division) */
603  return ((double)dy1 * dx2 == (double)dx1 * dy2);
604 }
605 
606 
620 static void updateConn( TRACK *track, std::shared_ptr<CONNECTIVITY_DATA> connectivity )
621 {
622  for( auto pad : connectivity->GetConnectedPads( track ) )
623  {
624  if( pad->HitTest( track->GetStart() ) )
625  {
626  track->SetState( START_ON_PAD, true );
627  }
628 
629  if( pad->HitTest( track->GetEnd() ) )
630  {
631  track->SetState( END_ON_PAD, true );
632  }
633  }
634 }
635 
636 
638  ENDPOINT_T aEndType )
639 {
640  // First of all, they must be of the same width and must be both actual tracks
641  if( ( aTrackRef->GetWidth() != aCandidate->GetWidth() ) ||
642  ( aTrackRef->Type() != PCB_TRACE_T ) ||
643  ( aCandidate->Type() != PCB_TRACE_T ) )
644  return NULL;
645 
646  // Trivial case: exactly the same track
647  if( ( aTrackRef->GetStart() == aCandidate->GetStart() ) &&
648  ( aTrackRef->GetEnd() == aCandidate->GetEnd() ) )
649  return aCandidate;
650 
651  if( ( aTrackRef->GetStart() == aCandidate->GetEnd() ) &&
652  ( aTrackRef->GetEnd() == aCandidate->GetStart() ) )
653  return aCandidate;
654 
655  // Weed out non-parallel tracks
656  if( !parallelismTest( aTrackRef->GetEnd().x - aTrackRef->GetStart().x,
657  aTrackRef->GetEnd().y - aTrackRef->GetStart().y,
658  aCandidate->GetEnd().x - aCandidate->GetStart().x,
659  aCandidate->GetEnd().y - aCandidate->GetStart().y ) )
660  return NULL;
661 
662  auto connectivity = m_brd->GetConnectivity();
663 
664  updateConn( aTrackRef, connectivity );
665  updateConn( aCandidate, connectivity );
666 
667  if( aEndType == ENDPOINT_START )
668  {
669  // We do not have a pad, which is a always terminal point for a track
670  if( aTrackRef->GetState( START_ON_PAD ) )
671  return NULL;
672 
673  /* change the common point coordinate of pt_segm to use the other point
674  * of pt_segm (pt_segm will be removed later) */
675  if( aTrackRef->GetStart() == aCandidate->GetStart() )
676  {
677  m_commit.Modify( aTrackRef );
678  aTrackRef->SetStart( aCandidate->GetEnd() );
679  aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( END_ON_PAD ) );
680  connectivity->Update( aTrackRef );
681  return aCandidate;
682  }
683  else
684  {
685  m_commit.Modify( aTrackRef );
686  aTrackRef->SetStart( aCandidate->GetStart() );
687  aTrackRef->SetState( START_ON_PAD, aCandidate->GetState( START_ON_PAD ) );
688  connectivity->Update( aTrackRef );
689  return aCandidate;
690  }
691  }
692  else // aEndType == END
693  {
694  // We do not have a pad, which is a always terminal point for a track
695  if( aTrackRef->GetState( END_ON_PAD ) )
696  return NULL;
697 
698  /* change the common point coordinate of pt_segm to use the other point
699  * of pt_segm (pt_segm will be removed later) */
700  if( aTrackRef->GetEnd() == aCandidate->GetStart() )
701  {
702  m_commit.Modify( aTrackRef );
703  aTrackRef->SetEnd( aCandidate->GetEnd() );
704  aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( END_ON_PAD ) );
705  connectivity->Update( aTrackRef );
706 
707  return aCandidate;
708  }
709  else
710  {
711  m_commit.Modify( aTrackRef );
712  aTrackRef->SetEnd( aCandidate->GetStart() );
713  aTrackRef->SetState( END_ON_PAD, aCandidate->GetState( START_ON_PAD ) );
714  connectivity->Update( aTrackRef );
715  return aCandidate;
716  }
717  }
718 
719  return NULL;
720 }
721 
722 
724 {
725  // Old model has to be refreshed, GAL normally does not keep updating it
726  Compile_Ratsnest( NULL, false );
727  BOARD_COMMIT commit( this );
728 
729  TRACKS_CLEANER cleaner( GetBoard(), commit );
730  bool isModified = cleaner.CleanupBoard( true, false, false, false );
731 
732  if( isModified )
733  {
734  // Clear undo and redo lists to avoid inconsistencies between lists
735  SetCurItem( NULL );
736  commit.Push( _( "Board cleanup" ) );
737  Compile_Ratsnest( NULL, true );
738  }
739 
740  m_canvas->Refresh( true );
741 
742  return isModified;
743 }
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:646
BOARD * m_brd
Definition: clean.cpp:120
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:269
TRACK * GetTrack(TRACK *aStartTrace, TRACK *aEndTrace, ENDPOINT_T aEndPoint, bool aSameNetOnly, bool aSequential)
Function GetTrack returns the trace segment connected to the segment at aEndPoint from aStartTrace to...
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
bool MergeCollinearTracks(TRACK *aSegment)
Try to merge the segment to a following collinear one.
Definition: clean.cpp:480
#define END_ON_PAD
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Update the board display after modifying it bu a python script (note: it is automatically called by a...
Definition: draw_panel.cpp:325
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:119
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool CleanupBoard(bool aCleanVias, bool aRemoveMisConnected, bool aMergeSegments, bool aDeleteUnconnected)
the cleanup function.
Definition: clean.cpp:207
static void updateConn(TRACK *track, std::shared_ptr< CONNECTIVITY_DATA > connectivity)
Function used by cleanupSegments.
Definition: clean.cpp:620
static bool parallelismTest(int dx1, int dy1, int dx2, int dy2)
Definition: clean.cpp:580
Class BOARD to handle a board.
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
bool deleteDanglingTracks()
Removes dangling tracks.
Definition: clean.cpp:382
BOARD * GetBoard() const
#define BUSY
Pcbnew: flag indicating that the structure has.
Definition: base_struct.h:148
TRACKS_CLEANER(BOARD *aPcb, BOARD_COMMIT &aCommit)
Definition: clean.cpp:252
bool testTrackEndpointDangling(TRACK *aTrack, ENDPOINT_T aEndPoint)
Utility: does the endpoint unconnected processed for one endpoint of one track Returns true if the tr...
Definition: clean.cpp:349
int GetState(int type) const
Definition: base_struct.h:251
#define START_ON_PAD
const wxPoint & GetEnd() const
Definition: class_track.h:120
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true) override
Executes the changes.
Functions relatives to tracks, vias and segments used to fill zones.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
BOARD_COMMIT & m_commit
Definition: clean.cpp:121
ENDPOINT_T
Flag used in locate routines (from which endpoint work)
Definition: pcbnew.h:54
void removeDuplicatesOfTrack(const TRACK *aTrack, std::set< BOARD_ITEM * > &aToRemove)
Removes all the following duplicates tracks of the specified one.
Definition: clean.cpp:445
COMMIT & Removed(EDA_ITEM *aItem)
Notifies observers that aItem has been removed
Definition: commit.h:96
Class LSET is a set of PCB_LAYER_IDs.
bool RemoveMisConnectedTracks()
Function RemoveMisConnectedTracks finds all track segments which are mis-connected (to more than one ...
Definition: clean.cpp:723
const wxPoint & GetStart() const
Definition: class_track.h:123
const wxPoint & GetEndPoint(ENDPOINT_T aEndPoint) const
Return the selected endpoint (start or end)
Definition: class_track.h:127
bool removeBadTrackSegments()
Definition: clean.cpp:259
#define STRUCT_DELETED
flag indication structures to be erased
Definition: base_struct.h:136
#define TRACK_LOCKED
Pcbnew: track locked: protected from global deletion.
Definition: base_struct.h:142
const ZONE_CONTAINER * zoneForTrackEndpoint(const TRACK *aTrack, ENDPOINT_T aEndPoint)
#define FLAG0
Pcbnew: flag used in local computations.
Definition: base_struct.h:145
void Compile_Ratsnest(wxDC *aDC, bool aDisplayStatus)
Function Compile_Ratsnest Create the entire board ratsnest.
Definition: ratsnest.cpp:56
int GetNetCode() const
Function GetNetCode.
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:93
TRACK * Next() const
Definition: class_track.h:100
TRACK * mergeCollinearSegmentIfPossible(TRACK *aTrackRef, TRACK *aCandidate, ENDPOINT_T aEndType)
helper function merge aTrackRef and aCandidate, when possible, i.e.
Definition: clean.cpp:637
void SetState(int type, int state)
Definition: base_struct.h:256
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...
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
int GetWidth() const
Definition: class_track.h:117
void SetStart(const wxPoint &aStart)
Definition: class_track.h:122
DLIST_ITERATOR_WRAPPER< TRACK > Tracks()
Definition: class_board.h:249
DLIST< TRACK > m_Track
Definition: class_board.h:246
bool cleanupSegments()
Merge collinear segments and remove duplicated and null len segments.
Definition: clean.cpp:534
void removeDuplicatesOfVia(const VIA *aVia, std::set< BOARD_ITEM * > &aToRemove)
Removes all the following THT vias on the same position of the specified one.
Definition: clean.cpp:286
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:290
bool deleteNullSegments()
Delete null length track segments.
Definition: clean.cpp:432
void Clean_Pcb()
Function Clean_Pcb Clean up the board (remove redundant vias, not connected tracks and merges colline...
Definition: clean.cpp:142
void Remove(BOARD_ITEM *aBoardItem) override
Removes an item from the container.
void buildTrackConnectionInfo()
helper function Rebuild list of tracks, and connected tracks this info must be rebuilt when tracks ar...
Definition: clean.cpp:170
bool removeItems(std::set< BOARD_ITEM * > &aItems)
Definition: clean.cpp:123
bool cleanupVias()
Removes redundant vias like vias at same location or on pad through.
Definition: clean.cpp:301
VIA * GetFirstVia(TRACK *aTrk, const TRACK *aStopPoint=NULL)
Scan a track list for the first VIA o NULL if not found (or NULL passed)
Definition: class_track.h:496