KiCad PCB EDA Suite
drc_test_provider_connectivity.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-2020 KiCad Developers.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <board.h>
25 #include <common.h>
26 
29 
30 #include <drc/drc_engine.h>
31 #include <drc/drc_item.h>
32 #include <drc/drc_rule.h>
33 #include <drc/drc_test_provider.h>
34 
35 
36 /*
37  Connectivity test provider. Not rule-driven.
38  Errors generated:
39  - DRCE_DANGLING_TRACK
40  - DRCE_DANGLING_VIA
41  - DRCE_ZONE_HAS_EMPTY_NET
42 */
43 
45 {
46 public:
48  {
49  }
50 
52  {
53  }
54 
55  virtual bool Run() override;
56 
57  virtual const wxString GetName() const override
58  {
59  return "connectivity";
60  };
61 
62  virtual const wxString GetDescription() const override
63  {
64  return "Tests board connectivity";
65  }
66 
67  virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
68 
69  int GetNumPhases() const override;
70 };
71 
72 
74 {
75  if( !reportPhase( _( "Checking pad, via and zone connections..." ) ) )
76  return false; // DRC cancelled
77 
78  BOARD* board = m_drcEngine->GetBoard();
79 
80  std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
81 
82  // Rebuild just in case. This really needs to be reliable.
83  connectivity->Clear();
84  connectivity->Build( board, m_drcEngine->GetProgressReporter() );
85 
86  int delta = 100; // This is the number of tests between 2 calls to the progress bar
87  int ii = 0;
88  int count = board->Tracks().size() + board->Zones().size();
89 
90  ii += count; // We gave half of this phase to CONNECTIVITY_DATA::Build()
91  count += count;
92 
93  for( PCB_TRACK* track : board->Tracks() )
94  {
97 
98  if( exceedV && exceedT )
99  break;
100  else if( track->Type() == PCB_VIA_T && exceedV )
101  continue;
102  else if( track->Type() == PCB_TRACE_T && exceedT )
103  continue;
104 
105  if( !reportProgress( ii++, count, delta ) )
106  break;
107 
108  // Test for dangling items
109  int code = track->Type() == PCB_VIA_T ? DRCE_DANGLING_VIA : DRCE_DANGLING_TRACK;
110  wxPoint pos;
111 
112  if( connectivity->TestTrackEndpointDangling( track, &pos ) )
113  {
114  std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( code );
115  drcItem->SetItems( track );
116  reportViolation( drcItem, pos );
117  }
118  }
119 
120  /* test starved zones */
121  for( ZONE* zone : board->Zones() )
122  {
124  break;
125 
126  if( !zone->IsOnCopperLayer() )
127  continue;
128 
129  if( !reportProgress( ii++, count, delta ) )
130  return false; // DRC cancelled
131 
132  int netcode = zone->GetNetCode();
133  // a netcode < 0 or > 0 and no pad in net is a error or strange
134  // perhaps a "dead" net, which happens when all pads in this net were removed
135  // Remark: a netcode < 0 should not happen (this is more a bug somewhere)
136  int pads_in_net = ( netcode > 0 ) ? connectivity->GetPadCount( netcode ) : 1;
137 
138  if( ( netcode < 0 ) || pads_in_net == 0 )
139  {
140  std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONE_HAS_EMPTY_NET );
141  drcItem->SetItems( zone );
142  reportViolation( drcItem, zone->GetPosition() );
143  }
144  }
145 
147  return true; // continue with other tests
148 
149  if( !reportPhase( _( "Checking net connections..." ) ) )
150  return false; // DRC cancelled
151 
152  connectivity->RecalculateRatsnest();
153  std::vector<CN_EDGE> edges;
154  connectivity->GetUnconnectedEdges( edges );
155 
156  delta = 250;
157  ii = 0;
158  count = edges.size();
159 
160  for( const CN_EDGE& edge : edges )
161  {
163  break;
164 
165  if( !reportProgress( ii++, count, delta ) )
166  return false; // DRC cancelled
167 
168  std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNCONNECTED_ITEMS );
169  drcItem->SetItems( edge.GetSourceNode()->Parent(), edge.GetTargetNode()->Parent() );
170  reportViolation( drcItem, (wxPoint) edge.GetSourceNode()->Pos() );
171  }
172 
174 
175  return true;
176 }
177 
178 
180 {
181  return 3;
182 }
183 
184 
185 std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_CONNECTIVITY::GetConstraintTypes() const
186 {
187  return {};
188 }
189 
190 
191 namespace detail
192 {
194 }
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:266
ZONES & Zones()
Definition: board.h:240
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const wxPoint &aMarkerPos)
bool IsErrorLimitExceeded(int error_code)
virtual bool reportProgress(int aCount, int aSize, int aDelta)
virtual const wxString GetName() const override
PROGRESS_REPORTER * GetProgressReporter() const
Definition: drc_engine.h:123
virtual void reportRuleStatistics()
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
BOARD * GetBoard() const
Definition: drc_engine.h:88
virtual bool reportPhase(const wxString &aStageName)
virtual const wxString GetDescription() const override
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:345
#define _(s)
Handle a list of polygons defining a copper zone.
Definition: zone.h:56
Represent a DRC "provider" which runs some DRC functions over a BOARD and spits out #DRC_ITEMs and po...
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:191
DRC_ENGINE * m_drcEngine
The common library.
constexpr int delta
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
TRACKS & Tracks()
Definition: board.h:231
virtual std::set< DRC_CONSTRAINT_T > GetConstraintTypes() const override