KiCad PCB EDA Suite
Loading...
Searching...
No Matches
drc_test_provider_misc.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.
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
25#include <drc/drc_engine.h>
26#include <drc/drc_item.h>
27#include <drc/drc_rule.h>
30#include <collectors.h>
31#include <pcb_shape.h>
32#include <pad.h>
33#include <pcb_track.h>
34
37
38#include <limits>
39
40/*
41 Miscellaneous tests:
42
43 - DRCE_DISABLED_LAYER_ITEM, ///< item on a disabled layer
44 - DRCE_INVALID_OUTLINE, ///< invalid board outline
45 - DRCE_UNRESOLVED_VARIABLE,
46 - DRCE_ASSERTION_FAILURE, ///< user-defined assertions
47 - DRCE_GENERIC_WARNING ///< user-defined warnings
48 - DRCE_GENERIC_ERROR ///< user-defined errors
49*/
50
51static void findClosestOutlineGap( BOARD* aBoard, PCB_SHAPE*& aItemA, PCB_SHAPE*& aItemB,
52 VECTOR2I& aMidpoint, int& aDistance )
53{
55 items.Collect( aBoard, { PCB_SHAPE_T } );
56
57 std::vector<PCB_SHAPE*> shapes;
58
59 for( int ii = 0; ii < items.GetCount(); ++ii )
60 {
61 PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( items[ii] );
62
63 if( shape->GetLayer() == Edge_Cuts )
64 shapes.push_back( shape );
65 }
66
67 int best = std::numeric_limits<int>::max();
68 VECTOR2I bestA;
69 VECTOR2I bestB;
70
71 for( size_t ii = 0; ii < shapes.size(); ++ii )
72 {
73 std::shared_ptr<SHAPE> shapeA = shapes[ii]->GetEffectiveShape();
74
75 for( size_t jj = ii + 1; jj < shapes.size(); ++jj )
76 {
77 std::shared_ptr<SHAPE> shapeB = shapes[jj]->GetEffectiveShape();
78 VECTOR2I ptA;
79 VECTOR2I ptB;
80
81 if( shapeA && shapeB && shapeA->NearestPoints( shapeB.get(), ptA, ptB ) )
82 {
83 int dist = ( ptA - ptB ).EuclideanNorm();
84
85 if( dist < best )
86 {
87 best = dist;
88 bestA = ptA;
89 bestB = ptB;
90 aItemA = shapes[ii];
91 aItemB = shapes[jj];
92 }
93 }
94 }
95 }
96
97 if( aItemA && aItemB )
98 {
99 aDistance = best;
100 aMidpoint = ( bestA + bestB ) / 2;
101 }
102 else
103 {
104 aDistance = 0;
105 aMidpoint = VECTOR2I();
106 }
107}
108
110{
111public:
113 m_board( nullptr )
114 {
115 m_isRuleDriven = false;
116 }
117
118 virtual ~DRC_TEST_PROVIDER_MISC() = default;
119
120 virtual bool Run() override;
121
122 virtual const wxString GetName() const override { return wxT( "miscellaneous" ); };
123
124private:
125 void testOutline();
126 void testDisabledLayers();
127 void testTextVars();
128 void testAssertions();
129
131};
132
133
135{
136 SHAPE_POLY_SET dummyOutline;
137 bool errorHandled = false;
138
139 OUTLINE_ERROR_HANDLER errorHandler =
140 [&]( const wxString& msg, BOARD_ITEM* itemA, BOARD_ITEM* itemB, const VECTOR2I& pt )
141 {
142 errorHandled = true;
143
144 if( m_drcEngine->IsErrorLimitExceeded( DRCE_INVALID_OUTLINE ) )
145 return;
146
147 if( !itemA ) // If we only have a single item, make sure it's A
148 std::swap( itemA, itemB );
149
150 VECTOR2I markerPos = pt;
151 int gap = 0;
152 PCB_SHAPE* shapeA = nullptr;
153 PCB_SHAPE* shapeB = nullptr;
154
155 if( itemA && itemB && itemA->Type() == PCB_SHAPE_T && itemB->Type() == PCB_SHAPE_T )
156 {
157 shapeA = static_cast<PCB_SHAPE*>( itemA );
158 shapeB = static_cast<PCB_SHAPE*>( itemB );
159 }
160 else
161 {
162 findClosestOutlineGap( m_board, shapeA, shapeB, markerPos, gap );
163
164 itemA = shapeA;
165 itemB = shapeB;
166 }
167
168 if( shapeA && shapeB )
169 {
170 VECTOR2I pts0[2] = { shapeA->GetStart(), shapeA->GetEnd() };
171 VECTOR2I pts1[2] = { shapeB->GetStart(), shapeB->GetEnd() };
172
173 SEG::ecoord d[4];
174 d[0] = ( pts0[0] - pts1[0] ).SquaredEuclideanNorm();
175 d[1] = ( pts0[0] - pts1[1] ).SquaredEuclideanNorm();
176 d[2] = ( pts0[1] - pts1[0] ).SquaredEuclideanNorm();
177 d[3] = ( pts0[1] - pts1[1] ).SquaredEuclideanNorm();
178
179 int idx = std::min_element( d, d + 4 ) - d;
180 gap = std::sqrt( d[idx] );
181 markerPos = ( pts0[idx / 2] + pts1[idx % 2] ) / 2;
182 }
183
184 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
185 wxString msg2;
186
187 if( itemA && itemB )
188 msg2.Printf( _( "%s (gap %s)" ), msg, MessageTextFromValue( gap ) );
189 else
190 msg2 = msg;
191
192 drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg2 );
193 drcItem->SetItems( itemA, itemB );
194
195 reportViolation( drcItem, markerPos, Edge_Cuts );
196 };
197
198 // Test for very small graphic items (a few nm size) that can create issues
199 // when trying to build the board outlines, and they are not easy to locate on screen.
200 const int minSizeForValideGraphics = pcbIUScale.mmToIU( 0.001 );
201
202 if( !TestBoardOutlinesGraphicItems(m_board, minSizeForValideGraphics, &errorHandler ) )
203 {
204 if( errorHandled )
205 {
206 // if there are invalid items on Edge.Cuts, they are already reported
207 }
208 else
209 {
210 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
211 wxString msg;
212
213 msg.Printf( _( "(Suspicious items found on Edge.Cuts layer)" ) );
214
215 drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
216 drcItem->SetItems( m_board );
217
218 reportViolation( drcItem, m_board->GetBoundingBox().Centre(), Edge_Cuts );
219 }
220 }
221
222
223 // Use the standard chaining epsilon here so that we report errors that might affect
224 // other tools (such as 3D viewer).
225 int chainingEpsilon = m_board->GetOutlinesChainingEpsilon();
226
227 // Arc to segment approximation error (not critical here: we do not use the outline shape):
228 int maxError = pcbIUScale.mmToIU( 0.05 );
229
230 if( !BuildBoardPolygonOutlines( m_board, dummyOutline, maxError, chainingEpsilon, &errorHandler ) )
231 {
232 if( errorHandled )
233 {
234 // if there is an invalid outline, then there must be an outline
235 }
236 else
237 {
238 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
239 wxString msg;
240
241 msg.Printf( _( "(no edges found on Edge.Cuts layer)" ) );
242
243 drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
244 drcItem->SetItems( m_board );
245
246 reportViolation( drcItem, m_board->GetBoundingBox().Centre(), Edge_Cuts );
247 }
248 }
249}
250
251
253{
254 const int progressDelta = 2000;
255 int ii = 0;
256 int items = 0;
257
258 auto countItems =
259 [&]( BOARD_ITEM* item ) -> bool
260 {
261 ++items;
262 return true;
263 };
264
265 LSET disabledLayers = LSET( m_board->GetEnabledLayers() ).flip();
266
267 // Perform the test only for copper layers
268 disabledLayers &= LSET::AllCuMask();
269
270 auto checkDisabledLayers =
271 [&]( BOARD_ITEM* item ) -> bool
272 {
273 if( m_drcEngine->IsErrorLimitExceeded( DRCE_DISABLED_LAYER_ITEM ) )
274 return false;
275
276 if( !reportProgress( ii++, items, progressDelta ) )
277 return false;
278
279 PCB_LAYER_ID badLayer = UNDEFINED_LAYER;
280
281 if( item->Type() == PCB_PAD_T )
282 {
283 PAD* pad = static_cast<PAD*>( item );
284
285 if( pad->GetAttribute() == PAD_ATTRIB::SMD
286 || pad->GetAttribute() == PAD_ATTRIB::CONN )
287 {
288 if( disabledLayers.test( pad->GetPrincipalLayer() ) )
289 badLayer = item->GetLayer();
290 }
291 else
292 {
293 // Through hole pad pierces all physical layers.
294 }
295 }
296 else if( item->Type() == PCB_VIA_T )
297 {
298 PCB_VIA* via = static_cast<PCB_VIA*>( item );
299 PCB_LAYER_ID top;
300 PCB_LAYER_ID bottom;
301
302 via->LayerPair( &top, &bottom );
303
304 if( disabledLayers.test( top ) )
305 badLayer = top;
306 else if( disabledLayers.test( bottom ) )
307 badLayer = bottom;
308 }
309 else if( item->Type() == PCB_ZONE_T )
310 {
311 // Footprint zones just get a top/bottom/inner setting, so they're on
312 // whatever inner layers there are.
313 }
314 else
315 {
316 LSET badLayers = disabledLayers & item->GetLayerSet();
317
318 if( badLayers.any() )
319 badLayer = badLayers.Seq().front();
320 }
321
322 if( badLayer != UNDEFINED_LAYER )
323 {
325 wxString msg;
326
327 msg.Printf( _( "(layer %s)" ), LayerName( badLayer ) );
328
329 drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
330 drcItem->SetItems( item );
331
332 reportViolation( drcItem, item->GetPosition(), UNDEFINED_LAYER );
333 }
334
335 return true;
336 };
337
340}
341
342
344{
345 const int progressDelta = 2000;
346 int ii = 0;
347 int items = 0;
348
349 auto countItems =
350 [&]( BOARD_ITEM* item ) -> bool
351 {
352 ++items;
353 return true;
354 };
355
356 auto checkAssertions =
357 [&]( BOARD_ITEM* item ) -> bool
358 {
359 if( !reportProgress( ii++, items, progressDelta ) )
360 return false;
361
362 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_ASSERTION_FAILURE ) )
363 {
364 m_drcEngine->ProcessAssertions( item,
365 [&]( const DRC_CONSTRAINT* c )
366 {
368 drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " (" )
369 + c->GetName() + wxS( ")" ) );
370 drcItem->SetItems( item );
371 drcItem->SetViolatingRule( c->GetParentRule() );
372
373 reportViolation( drcItem, item->GetPosition(), item->GetLayer() );
374 } );
375 }
376
377 return true;
378 };
379
380 forEachGeometryItem( {}, LSET::AllLayersMask(), countItems );
381 forEachGeometryItem( {}, LSET::AllLayersMask(), checkAssertions );
382}
383
384
386{
387 const int progressDelta = 2000;
388 int ii = 0;
389 int items = 0;
390
391 static const std::vector<KICAD_T> itemTypes = {
395 };
396
397 auto testAssertion =
398 [&]( BOARD_ITEM* item, const wxString& text, const VECTOR2I& pos, int layer )
399 {
400 static wxRegEx warningExpr( wxS( "^\\$\\{DRC_WARNING\\s*([^}]*)\\}(.*)$" ) );
401 static wxRegEx errorExpr( wxS( "^\\$\\{DRC_ERROR\\s*([^}]*)\\}(.*)$" ) );
402
403 if( warningExpr.Matches( text ) )
404 {
405 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_WARNING ) )
406 {
407 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_GENERIC_WARNING );
408 wxString drcText = warningExpr.GetMatch( text, 1 );
409
410 if( item )
411 drcItem->SetItems( item );
412 else
413 drcText += _( " (in drawing sheet)" );
414
415 drcItem->SetErrorMessage( drcText );
416
417 reportViolation( drcItem, pos, layer );
418 }
419
420 return true;
421 }
422
423 if( errorExpr.Matches( text ) )
424 {
425 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_ERROR ) )
426 {
427 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_GENERIC_ERROR );
428 wxString drcText = errorExpr.GetMatch( text, 1 );
429
430 if( item )
431 drcItem->SetItems( item );
432 else
433 drcText += _( " (in drawing sheet)" );
434
435 drcItem->SetErrorMessage( drcText );
436
437 reportViolation( drcItem, pos, layer );
438 }
439
440 return true;
441 }
442
443 return false;
444 };
445
447 [&]( BOARD_ITEM* item ) -> bool
448 {
449 ++items;
450 return true;
451 } );
452
454 [&]( BOARD_ITEM* item ) -> bool
455 {
456 if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
457 return false;
458
459 if( !reportProgress( ii++, items, progressDelta ) )
460 return false;
461
462 if( EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( item ) )
463 {
464 wxString result = ExpandEnvVarSubstitutions( textItem->GetShownText( true ),
465 nullptr /*project already done*/ );
466
467 if( result.Matches( wxT( "*${*}*" ) ) )
468 {
470 drcItem->SetItems( item );
471
472 reportViolation( drcItem, item->GetPosition(), item->GetLayer() );
473 }
474
475 testAssertion( item, textItem->GetText(), item->GetPosition(), item->GetLayer() );
476 }
477
478 return true;
479 } );
480
481 DS_PROXY_VIEW_ITEM* drawingSheet = m_drcEngine->GetDrawingSheet();
483
484 if( !drawingSheet || m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
485 return;
486
487 drawItems.SetPageNumber( wxT( "1" ) );
488 drawItems.SetSheetCount( 1 );
489 drawItems.SetFileName( wxT( "dummyFilename" ) );
490 drawItems.SetSheetName( wxT( "dummySheet" ) );
491 drawItems.SetSheetLayer( wxT( "dummyLayer" ) );
492 drawItems.SetProject( m_board->GetProject() );
493 drawItems.BuildDrawItemsList( drawingSheet->GetPageInfo(), drawingSheet->GetTitleBlock() );
494
495 for( DS_DRAW_ITEM_BASE* item = drawItems.GetFirst(); item; item = drawItems.GetNext() )
496 {
497 if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
498 break;
499
500 if( m_drcEngine->IsCancelled() )
501 return;
502
503 if( DS_DRAW_ITEM_TEXT* text = dynamic_cast<DS_DRAW_ITEM_TEXT*>( item ) )
504 {
505 if( testAssertion( nullptr, text->GetText(), text->GetPosition(), LAYER_DRAWINGSHEET ) )
506 {
507 // Don't run unresolved test
508 }
509 else if( text->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
510 {
511 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
512 drcItem->SetItems( drawingSheet );
513
514 reportViolation( drcItem, text->GetPosition(), LAYER_DRAWINGSHEET );
515 }
516 }
517 }
518}
519
520
522{
523 m_board = m_drcEngine->GetBoard();
524
525 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_INVALID_OUTLINE ) )
526 {
527 if( !reportPhase( _( "Checking board outline..." ) ) )
528 return false; // DRC cancelled
529
530 testOutline();
531 }
532
533 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_DISABLED_LAYER_ITEM ) )
534 {
535 if( !reportPhase( _( "Checking disabled layers..." ) ) )
536 return false; // DRC cancelled
537
539 }
540
541 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
542 {
543 if( !reportPhase( _( "Checking text variables..." ) ) )
544 return false; // DRC cancelled
545
546 testTextVars();
547 }
548
549 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_ASSERTION_FAILURE )
550 || !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_WARNING )
551 || !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_ERROR ) )
552 {
553 if( !reportPhase( _( "Checking assertions..." ) ) )
554 return false; // DRC cancelled
555
557 }
558
559 return !m_drcEngine->IsCancelled();
560}
561
562
563namespace detail
564{
566}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
BASE_SET & flip(size_t pos)
Definition base_set.h:160
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:79
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:232
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:317
int GetCount() const
Return the number of objects in the list.
Definition collector.h:83
wxString GetName() const
Definition drc_rule.h:170
DRC_RULE * GetParentRule() const
Definition drc_rule.h:166
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition drc_item.cpp:381
virtual const wxString GetName() const override
virtual ~DRC_TEST_PROVIDER_MISC()=default
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
virtual bool reportPhase(const wxString &aStageName)
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
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, const std::vector< PCB_SHAPE > &aShapes={})
virtual bool reportProgress(size_t aCount, size_t aSize, size_t aDelta=1)
Base class to handle basic graphic items.
Store the list of graphic items: rect, lines, polygons and texts to draw/plot the title block and fra...
DS_DRAW_ITEM_BASE * GetFirst()
void BuildDrawItemsList(const PAGE_INFO &aPageInfo, const TITLE_BLOCK &aTitleBlock)
Drawing or plot the drawing sheet.
void SetFileName(const wxString &aFileName)
Set the filename to draw/plot.
void SetSheetName(const wxString &aSheetName)
Set the sheet name to draw/plot.
void SetSheetLayer(const wxString &aSheetLayer)
Set the sheet layer to draw/plot.
void SetSheetCount(int aSheetCount)
Set the value of the count of sheets, for basic inscriptions.
void SetPageNumber(const wxString &aPageNumber)
Set the value of the sheet number.
DS_DRAW_ITEM_BASE * GetNext()
void SetProject(const PROJECT *aProject)
A graphic text.
virtual VECTOR2I GetPosition() const
Definition eda_item.h:272
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:215
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:173
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:79
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition lset.cpp:296
static const LSET & AllLayersMask()
Definition lset.cpp:624
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition lset.cpp:591
Definition pad.h:54
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition pcb_shape.h:71
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
Definition collectors.h:521
void Collect(BOARD_ITEM *aBoard, const std::vector< KICAD_T > &aTypes)
Collect BOARD_ITEM objects using this class's Inspector method, which does the collection.
VECTOR2I::extended_type ecoord
Definition seg.h:44
Represent a set of closed polygons.
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition common.cpp:355
#define FOR_ERC_DRC
Expand '${var-name}' templates in text.
Definition common.h:91
bool TestBoardOutlinesGraphicItems(BOARD *aBoard, int aMinDist, OUTLINE_ERROR_HANDLER *aErrorHandler)
Test a board graphic items on edge cut layer for validity.
bool BuildBoardPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
const std::function< void(const wxString &msg, BOARD_ITEM *itemA, BOARD_ITEM *itemB, const VECTOR2I &pt)> OUTLINE_ERROR_HANDLER
@ DRCE_DISABLED_LAYER_ITEM
Definition drc_item.h:71
@ DRCE_INVALID_OUTLINE
Definition drc_item.h:72
@ DRCE_GENERIC_ERROR
Definition drc_item.h:90
@ DRCE_UNRESOLVED_VARIABLE
Definition drc_item.h:87
@ DRCE_ASSERTION_FAILURE
Definition drc_item.h:88
@ DRCE_GENERIC_WARNING
Definition drc_item.h:89
static void findClosestOutlineGap(BOARD *aBoard, PCB_SHAPE *&aItemA, PCB_SHAPE *&aItemB, VECTOR2I &aMidpoint, int &aDistance)
#define _(s)
wxString LayerName(int aLayer)
Returns the default display name for a given layer.
Definition layer_id.cpp:31
@ LAYER_DRAWINGSHEET
Sheet frame and title block.
Definition layer_ids.h:277
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ Edge_Cuts
Definition layer_ids.h:112
@ UNDEFINED_LAYER
Definition layer_ids.h:61
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
@ SMD
Smd pad, appears on the solder paste layer (default)
Definition padstack.h:83
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
Definition padstack.h:84
wxString result
Test unit parsing edge cases and error handling.
@ 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
@ 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_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
Definition typeinfo.h:95
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:87
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition typeinfo.h:100
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695