KiCad PCB EDA Suite
Loading...
Searching...
No Matches
drc_test_provider.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 The KiCad Developers, see AUTHORS.txt for contributors.
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 "pcb_table.h"
25#include <drc/drc_item.h>
27#include <pcb_track.h>
28#include <footprint.h>
29#include <pad.h>
30#include <zone.h>
31#include <pcb_text.h>
32
33
34// A list of all basic (ie: non-compound) board geometry items
35std::vector<KICAD_T> DRC_TEST_PROVIDER::s_allBasicItems;
37
38
40{
41 for( DRC_TEST_PROVIDER* provider : m_providers )
42 delete provider;
43}
44
45
48 m_drcEngine( nullptr )
49{
50}
51
52
54{
55 if( s_allBasicItems.size() == 0 )
56 {
57 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
58 {
59 if( i != PCB_FOOTPRINT_T && i != PCB_GROUP_T )
60 {
61 s_allBasicItems.push_back( (KICAD_T) i );
62
63 if( i != PCB_ZONE_T )
64 s_allBasicItemsButZones.push_back( (KICAD_T) i );
65 }
66 }
67 }
68}
69
70
71const wxString DRC_TEST_PROVIDER::GetName() const { return wxT( "<no name test>" ); }
72
73
74void DRC_TEST_PROVIDER::reportViolation( std::shared_ptr<DRC_ITEM>& item,
75 const VECTOR2I& aMarkerPos, int aMarkerLayer,
76 DRC_CUSTOM_MARKER_HANDLER* aCustomHandler )
77{
78 item->SetViolatingTest( this );
79 m_drcEngine->ReportViolation( item, aMarkerPos, aMarkerLayer, aCustomHandler );
80}
81
82
83bool DRC_TEST_PROVIDER::reportProgress( size_t aCount, size_t aSize, size_t aDelta )
84{
85 if( ( aCount % aDelta ) == 0 || aCount == aSize - 1 )
86 {
87 if( !m_drcEngine->ReportProgress( static_cast<double>( aCount ) / aSize ) )
88 return false;
89 }
90
91 return true;
92}
93
94
95bool DRC_TEST_PROVIDER::reportPhase( const wxString& aMessage )
96{
97 REPORT_AUX( aMessage );
98 return m_drcEngine->ReportPhase( aMessage );
99}
100
101
102int DRC_TEST_PROVIDER::forEachGeometryItem( const std::vector<KICAD_T>& aTypes, const LSET& aLayers,
103 const std::function<bool( BOARD_ITEM*)>& aFunc )
104{
105 BOARD *brd = m_drcEngine->GetBoard();
106 std::bitset<MAX_STRUCT_TYPE_ID> typeMask;
107 int n = 0;
108
109 if( aTypes.size() == 0 )
110 {
111 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
112 typeMask[ i ] = true;
113 }
114 else
115 {
116 for( KICAD_T aType : aTypes )
117 typeMask[ aType ] = true;
118 }
119
120 for( PCB_TRACK* item : brd->Tracks() )
121 {
122 if( (item->GetLayerSet() & aLayers).any() )
123 {
124 if( typeMask[ PCB_TRACE_T ] && item->Type() == PCB_TRACE_T )
125 {
126 aFunc( item );
127 n++;
128 }
129 else if( typeMask[ PCB_VIA_T ] && item->Type() == PCB_VIA_T )
130 {
131 aFunc( item );
132 n++;
133 }
134 else if( typeMask[ PCB_ARC_T ] && item->Type() == PCB_ARC_T )
135 {
136 aFunc( item );
137 n++;
138 }
139 }
140 }
141
142 for( BOARD_ITEM* item : brd->Drawings() )
143 {
144 if( (item->GetLayerSet() & aLayers).any() )
145 {
146 if( typeMask[ PCB_DIMENSION_T ] && BaseType( item->Type() ) == PCB_DIMENSION_T )
147 {
148 if( !aFunc( item ) )
149 return n;
150
151 n++;
152 }
153 else if( typeMask[ PCB_SHAPE_T ] && item->Type() == PCB_SHAPE_T )
154 {
155 if( !aFunc( item ) )
156 return n;
157
158 n++;
159 }
160 else if( typeMask[ PCB_TEXT_T ] && item->Type() == PCB_TEXT_T )
161 {
162 if( !aFunc( item ) )
163 return n;
164
165 n++;
166 }
167 else if( typeMask[ PCB_TEXTBOX_T ] && item->Type() == PCB_TEXTBOX_T )
168 {
169 if( !aFunc( item ) )
170 return n;
171
172 n++;
173 }
174 else if( typeMask[ PCB_TARGET_T ] && item->Type() == PCB_TARGET_T )
175 {
176 if( !aFunc( item ) )
177 return n;
178
179 n++;
180 }
181 else if( item->Type() == PCB_TABLE_T )
182 {
183 if( typeMask[ PCB_TABLE_T ] )
184 {
185 if( !aFunc( item ) )
186 return n;
187
188 n++;
189 }
190
191 if( typeMask[ PCB_TABLECELL_T ] )
192 {
193 for( PCB_TABLECELL* cell : static_cast<PCB_TABLE*>( item )->GetCells() )
194 {
195 if( !aFunc( cell ) )
196 return n;
197
198 n++;
199 }
200 }
201 }
202 }
203 }
204
205 if( typeMask[ PCB_ZONE_T ] )
206 {
207 for( ZONE* item : brd->Zones() )
208 {
209 if( ( item->GetLayerSet() & aLayers ).any() )
210 {
211 if( !aFunc( item ) )
212 return n;
213
214 n++;
215 }
216 }
217 }
218
219 for( FOOTPRINT* footprint : brd->Footprints() )
220 {
221 if( typeMask[ PCB_FIELD_T ] )
222 {
223 for( PCB_FIELD* field : footprint->GetFields() )
224 {
225 if( ( field->GetLayerSet() & aLayers ).any() )
226 {
227 if( !aFunc( field ) )
228 return n;
229
230 n++;
231 }
232 }
233 }
234
235 if( typeMask[ PCB_PAD_T ] )
236 {
237 for( PAD* pad : footprint->Pads() )
238 {
239 // Careful: if a pad has a hole then it pierces all layers
240 if( pad->HasHole() || ( pad->GetLayerSet() & aLayers ).any() )
241 {
242 if( !aFunc( pad ) )
243 return n;
244
245 n++;
246 }
247 }
248 }
249
250 for( BOARD_ITEM* dwg : footprint->GraphicalItems() )
251 {
252 if( (dwg->GetLayerSet() & aLayers).any() )
253 {
254 if( typeMask[ PCB_DIMENSION_T ] && BaseType( dwg->Type() ) == PCB_DIMENSION_T )
255 {
256 if( !aFunc( dwg ) )
257 return n;
258
259 n++;
260 }
261 else if( typeMask[ PCB_TEXT_T ] && dwg->Type() == PCB_TEXT_T )
262 {
263 if( !aFunc( dwg ) )
264 return n;
265
266 n++;
267 }
268 else if( typeMask[ PCB_TEXTBOX_T ] && dwg->Type() == PCB_TEXTBOX_T )
269 {
270 if( !aFunc( dwg ) )
271 return n;
272
273 n++;
274 }
275 else if( typeMask[ PCB_SHAPE_T ] && dwg->Type() == PCB_SHAPE_T )
276 {
277 if( !aFunc( dwg ) )
278 return n;
279
280 n++;
281 }
282 }
283 }
284
285 if( typeMask[ PCB_ZONE_T ] )
286 {
287 for( ZONE* zone : footprint->Zones() )
288 {
289 if( (zone->GetLayerSet() & aLayers).any() )
290 {
291 if( !aFunc( zone ) )
292 return n;
293
294 n++;
295 }
296 }
297 }
298
299 if( typeMask[ PCB_FOOTPRINT_T ] )
300 {
301 if( !aFunc( footprint ) )
302 return n;
303
304 n++;
305 }
306 }
307
308 return n;
309}
310
311
313{
314 if( const PCB_FIELD* field = dynamic_cast<const PCB_FIELD*>( aItem ) )
315 {
316 if( !field->IsVisible() )
317 return true;
318 }
319
320 return false;
321}
322
323
324wxString DRC_TEST_PROVIDER::formatMsg( const wxString& aFormatString, const wxString& aSource,
325 double aConstraint, double aActual, EDA_DATA_TYPE aType )
326{
327 wxString constraint_str = MessageTextFromValue( aConstraint, true, aType );
328 wxString actual_str = MessageTextFromValue( aActual, true, aType );
329
330 if( constraint_str == actual_str )
331 {
332 // Use more precise formatting if the message-text strings were equal.
333 constraint_str = StringFromValue( aConstraint, true, aType );
334 actual_str = StringFromValue( aActual, true, aType );
335 }
336
337 return wxString::Format( aFormatString, aSource, std::move( constraint_str ), std::move( actual_str ) );
338}
339
340wxString DRC_TEST_PROVIDER::formatMsg( const wxString& aFormatString, const wxString& aSource,
341 const EDA_ANGLE& aConstraint, const EDA_ANGLE& aActual )
342{
343 wxString constraint_str = MessageTextFromValue( aConstraint );
344 wxString actual_str = MessageTextFromValue( aActual );
345
346 if( constraint_str == actual_str )
347 {
348 // Use more precise formatting if the message-text strings were equal.
349 constraint_str = StringFromValue( aConstraint, true );
350 actual_str = StringFromValue( aActual, true );
351 }
352
353 return wxString::Format( aFormatString, aSource, std::move( constraint_str ), std::move( actual_str ) );
354}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:112
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
const ZONES & Zones() const
Definition: board.h:362
const FOOTPRINTS & Footprints() const
Definition: board.h:358
const TRACKS & Tracks() const
Definition: board.h:356
const DRAWINGS & Drawings() const
Definition: board.h:360
void ReportViolation(const std::shared_ptr< DRC_ITEM > &aItem, const VECTOR2I &aPos, int aMarkerLayer, DRC_CUSTOM_MARKER_HANDLER *aCustomHandler=nullptr)
BOARD * GetBoard() const
Definition: drc_engine.h:100
bool ReportProgress(double aProgress)
bool ReportPhase(const wxString &aMessage)
std::vector< DRC_TEST_PROVIDER * > m_providers
Represent a DRC "provider" which runs some DRC functions over a BOARD and spits out DRC_ITEM and posi...
static std::vector< KICAD_T > s_allBasicItemsButZones
virtual bool reportPhase(const wxString &aStageName)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, DRC_CUSTOM_MARKER_HANDLER *aCustomHandler=nullptr)
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, const LSET &aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
static std::vector< KICAD_T > s_allBasicItems
DRC_ENGINE * m_drcEngine
bool isInvisibleText(const BOARD_ITEM *aItem) const
virtual const wxString GetName() const
wxString formatMsg(const wxString &aFormatString, const wxString &aSource, double aConstraint, double aActual, EDA_DATA_TYPE aDataType=EDA_DATA_TYPE::DISTANCE)
virtual bool reportProgress(size_t aCount, size_t aSize, size_t aDelta=1)
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
Definition: pad.h:54
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aValue in internal units into a united string.
Handle a list of polygons defining a copper zone.
Definition: zone.h:74
std::function< void(PCB_MARKER *aMarker)> DRC_CUSTOM_MARKER_HANDLER
Definition: drc_engine.h:68
#define REPORT_AUX(s)
EDA_DATA_TYPE
The type of unit.
Definition: eda_units.h:38
EDA_UNITS
Definition: eda_units.h:48
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:251
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ MAX_STRUCT_TYPE_ID
Definition: typeinfo.h:239
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:110
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:93
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:107
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition: typeinfo.h:90
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:106
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
Definition: typeinfo.h:95
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:100
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition: typeinfo.h:94
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96