KiCad PCB EDA Suite
drc_test_provider_annular_width.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 <common.h>
25 #include <pcb_track.h>
26 #include <drc/drc_engine.h>
27 #include <drc/drc_item.h>
28 #include <drc/drc_rule.h>
29 #include <drc/drc_test_provider.h>
30 
31 /*
32  Via/pad annular ring width test. Checks if there's sufficient copper ring around
33  PTH/NPTH holes (vias/pads)
34  Errors generated:
35  - DRCE_ANNULAR_WIDTH
36 
37  Todo:
38  - check pad holes too.
39  - pad stack support (different IAR/OAR values depending on layer)
40 */
41 
43 {
44 public:
46  {
47  }
48 
50  {
51  }
52 
53  virtual bool Run() override;
54 
55  virtual const wxString GetName() const override
56  {
57  return "annular_width";
58  };
59 
60  virtual const wxString GetDescription() const override
61  {
62  return "Tests pad/via annular rings";
63  }
64 
65  virtual std::set<DRC_CONSTRAINT_T> GetConstraintTypes() const override;
66 
67  int GetNumPhases() const override;
68 };
69 
70 
72 {
74  {
75  reportAux( "Annular width violations ignored. Skipping check." );
76  return true; // continue with other tests
77  }
78 
79  const int delta = 250; // This is the number of tests between 2 calls to the progress bar
80 
82  {
83  reportAux( "No annular width constraints found. Tests not run." );
84  return true; // continue with other tests
85  }
86 
87  if( !reportPhase( _( "Checking via annular rings..." ) ) )
88  return false; // DRC cancelled
89 
90  auto checkAnnularWidth =
91  [&]( BOARD_ITEM* item ) -> bool
92  {
94  return false;
95 
96  int v_min = 0;
97  int v_max = 0;
98  PCB_VIA* via = dyn_cast<PCB_VIA*>( item );
99 
100  // fixme: check minimum IAR/OAR ring for THT pads too
101  if( !via )
102  return true;
103 
104  // PADSTACKS TODO: once we have padstacks we'll need to run this per-layer....
105  auto constraint = m_drcEngine->EvalRules( ANNULAR_WIDTH_CONSTRAINT, via, nullptr,
106  UNDEFINED_LAYER );
107  int annularWidth = ( via->GetWidth() - via->GetDrillValue() ) / 2;
108  bool fail_min = false;
109  bool fail_max = false;
110 
111  if( constraint.Value().HasMin() )
112  {
113  v_min = constraint.Value().Min();
114  fail_min = annularWidth < v_min;
115  }
116 
117  if( constraint.Value().HasMax() )
118  {
119  v_max = constraint.Value().Max();
120  fail_max = annularWidth > v_max;
121  }
122 
123  if( fail_min || fail_max )
124  {
125  std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ANNULAR_WIDTH );
126 
127  if( fail_min )
128  m_msg.Printf( _( "(%s min annular width %s; actual %s)" ),
129  constraint.GetName(),
130  MessageTextFromValue( userUnits(), v_min ),
131  MessageTextFromValue( userUnits(), annularWidth ) );
132 
133  if( fail_max )
134  m_msg.Printf( _( "(%s max annular width %s; actual %s)" ),
135  constraint.GetName(),
136  MessageTextFromValue( userUnits(), v_max ),
137  MessageTextFromValue( userUnits(), annularWidth ) );
138 
139  drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
140  drcItem->SetItems( item );
141  drcItem->SetViolatingRule( constraint.GetParentRule() );
142 
143  reportViolation( drcItem, via->GetPosition() );
144  }
145 
146  return true;
147  };
148 
149  BOARD* board = m_drcEngine->GetBoard();
150  int ii = 0;
151 
152  for( PCB_TRACK* item : board->Tracks() )
153  {
154  if( !reportProgress( ii++, board->Tracks().size(), delta ) )
155  break;
156 
157  if( !checkAnnularWidth( item ) )
158  return false; // DRC cancelled
159  }
160 
162 
163  return true;
164 }
165 
166 
168 {
169  return 1;
170 }
171 
172 
173 std::set<DRC_CONSTRAINT_T> DRC_TEST_PROVIDER_ANNULAR_WIDTH::GetConstraintTypes() const
174 {
175  return { ANNULAR_WIDTH_CONSTRAINT };
176 }
177 
178 
179 namespace detail
180 {
182 }
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:104
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:266
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:49
MINOPTMAX< int > & Value()
Definition: drc_rule.h:123
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)
T Min() const
Definition: minoptmax.h:33
virtual void reportRuleStatistics()
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
bool HasRulesForConstraintType(DRC_CONSTRAINT_T constraintID)
BOARD * GetBoard() const
Definition: drc_engine.h:88
virtual const wxString GetName() const override
virtual bool reportPhase(const wxString &aStageName)
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
#define _(s)
virtual std::set< DRC_CONSTRAINT_T > GetConstraintTypes() const override
EDA_UNITS userUnits() const
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
Definition: drc_engine.cpp:760
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.
virtual const wxString GetDescription() const override
constexpr int delta
TRACKS & Tracks()
Definition: board.h:231
virtual void reportAux(wxString fmt,...)