41 m_itemsList( nullptr )
53 bool aRemoveMisConnected,
bool aCleanVias,
bool aMergeSegments,
54 bool aDeleteUnconnected,
bool aDeleteTracksinPad,
bool aDeleteDanglingVias )
56 bool has_deleted =
false;
61 cleanup( aCleanVias, aMergeSegments || aRemoveMisConnected, aMergeSegments, aMergeSegments );
63 if( aRemoveMisConnected )
66 if( aDeleteTracksinPad )
71 if( has_deleted && aMergeSegments )
72 cleanup(
false,
false,
false,
true );
80 std::set<BOARD_ITEM *> toRemove;
85 if( segment->IsLocked() )
88 for(
PAD* testedPad : connectivity->GetConnectedPads( segment ) )
90 if( segment->GetNetCode() != testedPad->GetNetCode() )
92 std::shared_ptr<CLEANUP_ITEM> item;
99 item->SetItems( segment );
102 toRemove.insert( segment );
106 for(
PCB_TRACK* testedTrack : connectivity->GetConnectedTracks( segment ) )
108 if( segment->GetNetCode() != testedTrack->GetNetCode() )
110 std::shared_ptr<CLEANUP_ITEM> item;
117 item->SetItems( segment );
120 toRemove.insert( segment );
135 auto items = connectivity->GetConnectivityAlgo()->ItemEntry( aTrack ).GetItems();
140 auto citem = items.front();
142 if( !citem->Valid() )
145 auto anchors = citem->Anchors();
149 for(
const auto&
anchor : anchors )
151 if(
anchor->Pos() != refpoint )
156 return anchor->ConnectedItemsCount() > 1;
165 bool item_erased =
false;
166 bool modified =
false;
168 if( !aTrack && !aVia )
178 std::deque<PCB_TRACK*> temp_tracks(
m_brd->
Tracks() );
182 if( track->IsLocked() || ( track->GetFlags() &
IS_DELETED ) > 0 )
185 if( !aVia && track->Type() ==
PCB_VIA_T )
194 std::shared_ptr<CLEANUP_ITEM> item;
201 item->SetItems( track );
217 }
while( item_erased );
225 std::set<BOARD_ITEM*> toRemove;
232 if( track->IsLocked() )
239 for(
PAD*
pad : connectivity->GetConnectedPads( track ) )
241 if(
pad->HitTest( track->GetStart() ) &&
pad->HitTest( track->GetEnd() ) )
244 track->TransformShapeWithClearanceToPolygon( poly, track->GetLayer(), 0,
252 item->SetItems( track );
255 toRemove.insert( track );
271 bool aDeleteDuplicateSegments,
bool aMergeSegments )
279 rtree.
Insert( track, track->GetLayer() );
282 std::set<BOARD_ITEM*> toRemove;
286 if( track->HasFlag(
IS_DELETED ) || track->IsLocked() )
289 if( aDeleteDuplicateVias && track->Type() ==
PCB_VIA_T )
291 PCB_VIA*
via = static_cast<PCB_VIA*>( track );
293 if(
via->GetStart() !=
via->GetEnd() )
294 via->SetEnd(
via->GetStart() );
307 PCB_VIA* other = static_cast<PCB_VIA*>( aItem );
314 item->SetItems(
via );
318 toRemove.insert(
via );
330 if( (
pad->GetLayerSet() & all_cu ) == all_cu )
333 item->SetItems(
via,
pad );
337 toRemove.insert(
via );
345 if( aDeleteNullSegments && track->Type() !=
PCB_VIA_T )
347 if( track->IsNull() )
350 item->SetItems( track );
354 toRemove.insert( track );
358 if( aDeleteDuplicateSegments && track->Type() ==
PCB_TRACE_T && !track->IsNull() )
360 rtree.
QueryColliding( track, track->GetLayer(), track->GetLayer(),
367 && !static_cast<PCB_TRACK*>( aItem )->IsNull();
372 PCB_TRACK* other = static_cast<PCB_TRACK*>( aItem );
374 if( track->IsPointOnEnds( other->
GetStart() )
375 && track->IsPointOnEnds( other->
GetEnd() )
376 && track->GetWidth() == other->
GetWidth()
377 && track->GetLayer() == other->
GetLayer() )
380 item->SetItems( track );
384 toRemove.insert( track );
409 std::deque<PCB_TRACK*> temp_segments(
m_brd->
Tracks() );
412 for(
PCB_TRACK* segment : temp_segments )
421 std::vector<BOARD_CONNECTED_ITEM*> connectedItems =
425 for(
CN_ITEM* citem : connectivity->ItemEntry( segment ).GetItems() )
429 std::vector<PCB_TRACK*> sameWidthCandidates;
430 std::vector<PCB_TRACK*> differentWidthCandidates;
434 if( !connected->Valid() )
441 PCB_TRACK* candidateSegment = static_cast<PCB_TRACK*>( candidate );
443 if( candidateSegment->
GetWidth() == segment->GetWidth() )
445 sameWidthCandidates.push_back( candidateSegment );
449 differentWidthCandidates.push_back( candidateSegment );
455 if( !differentWidthCandidates.empty() )
458 for(
PCB_TRACK* candidate : sameWidthCandidates )
460 if( segment->ApproxCollinear( *candidate )
478 const std::vector<BOARD_CONNECTED_ITEM*>& aSeg1Items )
487 std::vector<BOARD_CONNECTED_ITEM*> tracks = aSeg1Items;
488 std::vector<BOARD_CONNECTED_ITEM*> tracks2 = connectivity->GetConnectedItems( aSeg2, types );
490 std::move( tracks2.begin(), tracks2.end(), std::back_inserter( tracks ) );
491 std::sort( tracks.begin(), tracks.end() );
492 tracks.erase( std::unique( tracks.begin(), tracks.end() ), tracks.end() );
494 tracks.erase( std::remove_if( tracks.begin(), tracks.end(),
497 return ( aTest == aSeg1 ) || ( aTest == aSeg2 );
501 std::set<VECTOR2I> pts;
507 if(
PCB_TRACK* track = dyn_cast<PCB_TRACK*>( citem ) )
509 if( track->IsPointOnEnds( aSeg1->
GetStart() ) )
512 if( track->IsPointOnEnds( aSeg1->
GetEnd() ) )
513 pts.emplace( aSeg1->
GetEnd() );
515 if( track->IsPointOnEnds( aSeg2->
GetStart() ) )
518 if( track->IsPointOnEnds( aSeg2->
GetEnd() ) )
519 pts.emplace( aSeg2->
GetEnd() );
526 if( citem->HitTest( aSeg1->
GetEnd(), ( aSeg1->
GetWidth() + 1 ) / 2 ) )
527 pts.emplace( aSeg1->
GetEnd() );
532 if( citem->HitTest( aSeg2->
GetEnd(), ( aSeg2->
GetWidth() + 1 ) / 2 ) )
533 pts.emplace( aSeg2->
GetEnd() );
547 int min_x = std::min( aSeg1->
GetStart().x,
549 int min_y = std::min( aSeg1->
GetStart().y,
551 int max_x = std::max( aSeg1->
GetStart().x,
553 int max_y = std::max( aSeg1->
GetStart().y,
559 dummy_seg.
SetStart( wxPoint( min_x, min_y ) );
560 dummy_seg.
SetEnd( wxPoint( max_x, max_y ) );
564 dummy_seg.
SetStart( wxPoint( min_x, max_y ) );
565 dummy_seg.
SetEnd( wxPoint( max_x, min_y ) );
577 dummy_seg.
SetStart( wxPoint( pt.x, pt.y ) );
579 dummy_seg.
SetEnd( wxPoint( pt.x, pt.y ) );
597 item->SetItems( aSeg1, aSeg2 );
607 connectivity->Update( aSeg1 );
610 for(
auto pad : connectivity->GetConnectedPads( aSeg1 ) )
627 for(
auto item : aItems )
const CONNECTED_ITEMS & ConnectedItems() const
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
wxPoint GetPosition() const override
const wxPoint & GetEnd() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
void SetEnd(const wxPoint &aEnd)
VIATYPE GetViaType() const
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
void SetFlags(EDA_ITEM_FLAGS aMask)
class PCB_ARC, an arc track segment on a copper layer
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
class PAD, a pad in a footprint
TRACKS_CLEANER(BOARD *aPcb, BOARD_COMMIT &aCommit)
void removeShortingTrackSegments()
virtual bool IsLocked() const
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
class PCB_TRACK, a track segment (segment on a copper layer)
COMMIT & Removed(EDA_ITEM *aItem)
Modify a given item in the model.
void SetState(EDA_ITEM_FLAGS type, bool state)
LSET is a set of PCB_LAYER_IDs.
void cleanup(bool aDeleteDuplicateVias, bool aDeleteNullSegments, bool aDeleteDuplicateSegments, bool aMergeSegments)
Geometry-based cleanup: duplicate items, null items, colinear items.
bool deleteDanglingTracks(bool aTrack, bool aVia)
Removes tracks or vias only connected on one end.
Represent a set of closed polygons.
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
void removeItems(std::set< BOARD_ITEM * > &aItems)
void SetStart(const wxPoint &aStart)
class ZONE, a copper pour area
void CleanupBoard(bool aDryRun, std::vector< std::shared_ptr< CLEANUP_ITEM > > *aItemsList, bool aCleanVias, bool aRemoveMisConnected, bool aMergeSegments, bool aDeleteUnconnected, bool aDeleteTracksinPad, bool aDeleteDanglingVias)
the cleanup function.
bool mergeCollinearSegments(PCB_TRACK *aSeg1, PCB_TRACK *aSeg2, const std::vector< BOARD_CONNECTED_ITEM * > &aSeg1Items)
helper function merge aTrackRef and aCandidate, when possible, i.e.
void BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
#define BEGIN_ONPAD
Pcbnew: flag set for track segment starting on a pad.
#define SKIP_STRUCT
flag indicating that the structure should be ignored
std::vector< std::shared_ptr< CLEANUP_ITEM > > * m_itemsList
Information pertinent to a Pcbnew printed circuit board.
EDA_ITEM_FLAGS IsPointOnEnds(const wxPoint &point, int min_dist=0) const
Function IsPointOnEnds returns STARTPOINT if point if near (dist = min_dist) start point,...
CN_ITEM represents a BOARD_CONNETED_ITEM in the connectivity system (ie: a pad, track/arc/via,...
void deleteTracksInPads()
bool testTrackEndpointIsNode(PCB_TRACK *aTrack, bool aTstStart)
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
void Insert(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer, int aWorstClearance=0)
Insert an item into the tree on a particular layer with an optional worst clearance.
class PCB_VIA, a via (like a track segment on a copper layer)
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset intersection For aFastMode meaning, see function booleanOp.
Implement an R-tree for fast spatial and layer indexing of connectable items.
#define END_ONPAD
Pcbnew: flag set for track segment ending on a pad.
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
const wxPoint & GetStart() const
KICAD_T Type() const
Returns the type of object.
int QueryColliding(BOARD_ITEM *aRefItem, PCB_LAYER_ID aRefLayer, PCB_LAYER_ID aTargetLayer, std::function< bool(BOARD_ITEM *)> aFilter=nullptr, std::function< bool(BOARD_ITEM *)> aVisitor=nullptr, int aClearance=0) const
This is a fast test which essentially does bounding-box overlap given a worst-case clearance.