File: tracks_cleaner.h

package info (click to toggle)
kicad 9.0.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 770,320 kB
  • sloc: cpp: 961,692; ansic: 121,001; xml: 66,428; python: 18,387; sh: 1,010; awk: 301; asm: 292; makefile: 227; javascript: 167; perl: 10
file content (135 lines) | stat: -rw-r--r-- 5,217 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you may find one here:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * or you may search the http://www.gnu.org website for the version 2 license,
 * or you may write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */

#ifndef KICAD_TRACKS_CLEANER_H
#define KICAD_TRACKS_CLEANER_H

#include <mutex>
#include <pcb_track.h>
#include <board.h>

class BOARD_COMMIT;
class CLEANUP_ITEM;
class REPORTER;


// Helper class used to clean tracks and vias
class TRACKS_CLEANER
{
public:
    TRACKS_CLEANER( BOARD* aPcb, BOARD_COMMIT& aCommit );

    /**
     * the cleanup function.
     * @param aDryRun = true to build changes list, false to modify the board
     * @param aItemsList = list of modified items
     * @param aCleanVias = true to remove superimposed vias
     * @param aRemoveMisConnected = true to remove segments connecting 2 different nets
     *                              (short circuits)
     * @param aMergeSegments = true to merge collinear segmenst and remove 0 len segm
     * @param aDeleteUnconnected = true to remove dangling tracks
     * @param aDeleteTracksinPad = true to remove tracks fully inside pads
     * @param aDeleteDanglingVias = true to remove a via that is only connected to a single layer
     * @param aReporter is a REPORTER to print activity and info
     */
    void CleanupBoard( bool aDryRun, std::vector<std::shared_ptr<CLEANUP_ITEM> >* aItemsList,
                       bool aCleanVias, bool aRemoveMisConnected, bool aMergeSegments,
                       bool aDeleteUnconnected, bool aDeleteTracksinPad, bool aDeleteDanglingVias,
                       REPORTER* aReporter = nullptr );

    void SetFilter( const std::function<bool( BOARD_CONNECTED_ITEM* aItem )>& aFilter )
    {
        m_filter = aFilter;
    }

private:
    bool filterItem( BOARD_CONNECTED_ITEM* aItem );

    /*
     * Removes track segments which are connected to more than one net (short circuits).
     */
    void removeShortingTrackSegments();

    /**
     * Removes tracks or vias only connected on one end
     * @param aTrack if true, clean dangling tracks
     * @param aVia if true, clean dangling vias
     * @return true if any items were deleted
     */
    bool deleteDanglingTracks( bool aTrack, bool aVia );

    void deleteTracksInPads();

    /**
     * Geometry-based cleanup: duplicate items, null items, colinear items.
     */
    void cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegments,
                  bool aDeleteDuplicateSegments, bool aMergeSegments );

    /**
     * helper function
     * merge aTrackRef and aCandidate, when possible,
     * i.e. when they are colinear, same width, and obviously same layer
     * @return true if the segments are merged, false if not
     * @param aSeg1 is the reference
     * @param aSeg2 is the candidate, and after merging, the removed segment
     */
    bool mergeCollinearSegments( PCB_TRACK* aSeg1, PCB_TRACK* aSeg2 );

    /**
     * helper function
     * test if 2 segments are colinear.  Does not modify the connectivity
     * @return true if the segments are colinear
     * @param aSeg1 is the reference
     * @param aSeg2 is the candidate
     */
    bool testMergeCollinearSegments( PCB_TRACK* aSeg1, PCB_TRACK* aSeg2, PCB_TRACK* aDummySeg = nullptr );

    /**
     * @return true if a track end position is a node, i.e. a end connected
     * to more than one item.
     * @param aTrack is the track to test.
     * @param aTstStart = true ot test the start point of the track or false for end point
     */
    bool testTrackEndpointIsNode( PCB_TRACK* aTrack, bool aTstStart, bool aTstEnd );

    void removeItems( std::set<BOARD_ITEM*>& aItems );

    const std::vector<BOARD_CONNECTED_ITEM*>& getConnectedItems( PCB_TRACK* aTrack );

private:
    BOARD*                                      m_brd;
    BOARD_COMMIT&                               m_commit;       // caller owns
    bool                                        m_dryRun;
    std::vector<std::shared_ptr<CLEANUP_ITEM>>* m_itemsList;    // caller owns
    REPORTER*                                   m_reporter;

    // Cache connections.  O(n^2) is awful, but it beats O(2n^3).
    std::map<PCB_TRACK*, std::vector<BOARD_CONNECTED_ITEM*>> m_connectedItemsCache;

    std::function<bool( BOARD_CONNECTED_ITEM* aItem )>       m_filter;
    std::mutex m_mutex;
};


#endif //KICAD_TRACKS_CLEANER_H