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, see <https://www.gnu.org/licenses/>.
18 */
19
22#include <drc/drc_engine.h>
23#include <drc/drc_item.h>
24#include <drc/drc_rule.h>
27#include <collectors.h>
28#include <pcb_shape.h>
29#include <pad.h>
30#include <pcb_track.h>
31
34
35#include <thread_pool.h>
36
37#include <atomic>
38#include <limits>
41
42/*
43 Miscellaneous tests:
44
45 - DRCE_DISABLED_LAYER_ITEM, ///< item on a disabled layer
46 - DRCE_INVALID_OUTLINE, ///< invalid board outline
47 - DRCE_UNRESOLVED_VARIABLE,
48 - DRCE_ASSERTION_FAILURE, ///< user-defined assertions
49 - DRCE_GENERIC_WARNING ///< user-defined warnings
50 - DRCE_GENERIC_ERROR ///< user-defined errors
51 - DRCE_MISSING_TUNING_PROFILES ///< tuning profile for netc lass not defined
52*/
53
54static void findClosestOutlineGap( BOARD* aBoard, PCB_SHAPE*& aItemA, PCB_SHAPE*& aItemB,
55 VECTOR2I& aMidpoint, int& aDistance )
56{
58 items.Collect( aBoard, { PCB_SHAPE_T } );
59
60 std::vector<PCB_SHAPE*> shapes;
61
62 for( int ii = 0; ii < items.GetCount(); ++ii )
63 {
64 PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( items[ii] );
65
66 if( shape->GetLayer() == Edge_Cuts )
67 shapes.push_back( shape );
68 }
69
70 int best = std::numeric_limits<int>::max();
71 VECTOR2I bestA;
72 VECTOR2I bestB;
73
74 for( size_t ii = 0; ii < shapes.size(); ++ii )
75 {
76 std::shared_ptr<SHAPE> shapeA = shapes[ii]->GetEffectiveShape();
77
78 for( size_t jj = ii + 1; jj < shapes.size(); ++jj )
79 {
80 std::shared_ptr<SHAPE> shapeB = shapes[jj]->GetEffectiveShape();
81 VECTOR2I ptA;
82 VECTOR2I ptB;
83
84 if( shapeA && shapeB && shapeA->NearestPoints( shapeB.get(), ptA, ptB ) )
85 {
86 int dist = ( ptA - ptB ).EuclideanNorm();
87
88 if( dist < best )
89 {
90 best = dist;
91 bestA = ptA;
92 bestB = ptB;
93 aItemA = shapes[ii];
94 aItemB = shapes[jj];
95 }
96 }
97 }
98 }
99
100 if( aItemA && aItemB )
101 {
102 aDistance = best;
103 aMidpoint = ( bestA + bestB ) / 2;
104 }
105 else
106 {
107 aDistance = 0;
108 aMidpoint = VECTOR2I();
109 }
110}
111
113{
114public:
116 m_board( nullptr )
117 {
118 m_isRuleDriven = false;
119 }
120
121 virtual ~DRC_TEST_PROVIDER_MISC() = default;
122
123 virtual bool Run() override;
124
125 virtual const wxString GetName() const override { return wxT( "miscellaneous" ); };
126
127private:
128 void testOutline();
129 void testDisabledLayers();
130 void testTextVars();
131 void testAssertions();
133
135};
136
137
139{
140 SHAPE_POLY_SET dummyOutline;
141 bool errorHandled = false;
142
143 OUTLINE_ERROR_HANDLER errorHandler =
144 [&]( const wxString& msg, BOARD_ITEM* itemA, BOARD_ITEM* itemB, const VECTOR2I& pt )
145 {
146 errorHandled = true;
147
148 if( m_drcEngine->IsErrorLimitExceeded( DRCE_INVALID_OUTLINE ) )
149 return;
150
151 if( !itemA )
152 std::swap( itemA, itemB );
153
154 VECTOR2I markerPos = pt;
155 int gap = 0;
156 PCB_SHAPE* shapeA = nullptr;
157 PCB_SHAPE* shapeB = nullptr;
158 bool usedGap = false;
159
160 if( itemA && itemB && itemA->Type() == PCB_SHAPE_T && itemB->Type() == PCB_SHAPE_T )
161 {
162 shapeA = static_cast<PCB_SHAPE*>( itemA );
163 shapeB = static_cast<PCB_SHAPE*>( itemB );
164 }
165 else if( itemA && !itemB && itemA->Type() == PCB_SHAPE_T )
166 {
167 // A single item was flagged (e.g. a degenerate shape). Keep the marker
168 // at that item so the user can locate the bad geometry.
169 shapeA = static_cast<PCB_SHAPE*>( itemA );
170 }
171 else
172 {
173 // No usable item pair identified. Look for the most likely culprits.
174 findClosestOutlineGap( m_board, shapeA, shapeB, markerPos, gap );
175 itemA = shapeA;
176 itemB = shapeB;
177 usedGap = shapeA && shapeB;
178 }
179
180 if( shapeA && shapeB )
181 {
182 std::shared_ptr<SHAPE> effectiveShapeA = shapeA->GetEffectiveShape();
183 std::shared_ptr<SHAPE> effectiveShapeB = shapeB->GetEffectiveShape();
184
185 if( effectiveShapeA && effectiveShapeB )
186 {
187 BOX2I bboxA = effectiveShapeA->BBox();
188 BOX2I bboxB = effectiveShapeB->BBox();
189 BOX2I overlap = bboxA.Intersect( bboxB );
190
191 if( overlap.GetWidth() > 0 && overlap.GetHeight() > 0 )
192 {
193 markerPos = overlap.Centre();
194 usedGap = false;
195 }
196 else
197 {
198 VECTOR2I ptA, ptB;
199
200 if( effectiveShapeA->NearestPoints( effectiveShapeB.get(), ptA, ptB ) )
201 {
202 gap = ( ptA - ptB ).EuclideanNorm();
203 markerPos = ( ptA + ptB ) / 2;
204 usedGap = true;
205 }
206 }
207 }
208 }
209
210 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
211
212 if( itemA && itemB && usedGap )
213 {
214 drcItem->SetErrorDetail( wxString::Format( _( "%s (gap %s)" ), msg, MessageTextFromValue( gap ) ) );
215 }
216 else
217 {
218 drcItem->SetErrorDetail( msg );
219 }
220
221 drcItem->SetItems( itemA, itemB );
222
223 reportViolation( drcItem, markerPos, Edge_Cuts );
224 };
225
226 // Test for very small graphic items (a few nm size) that can create issues
227 // when trying to build the board outlines, and they are not easy to locate on screen.
228 const int minSizeForValideGraphics = pcbIUScale.mmToIU( 0.001 );
229
230 if( !TestBoardOutlinesGraphicItems(m_board, minSizeForValideGraphics, &errorHandler ) )
231 {
232 if( errorHandled )
233 {
234 // if there are invalid items on Edge.Cuts, they are already reported
235 }
236 else
237 {
238 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
239 drcItem->SetErrorDetail( _( "(Suspicious items found on Edge.Cuts layer)" ) );
240 drcItem->SetItems( m_board );
241
242 reportViolation( drcItem, m_board->GetBoundingBox().Centre(), Edge_Cuts );
243 }
244 }
245
246
247 // Use the standard chaining epsilon here so that we report errors that might affect
248 // other tools (such as 3D viewer).
249 int chainingEpsilon = m_board->GetOutlinesChainingEpsilon();
250
251 // Arc to segment approximation error (not critical here: we do not use the outline shape):
252 int maxError = pcbIUScale.mmToIU( 0.05 );
253
254 if( !BuildBoardPolygonOutlines( m_board, dummyOutline, maxError, chainingEpsilon, true, &errorHandler ) )
255 {
256 if( errorHandled )
257 {
258 // if there is an invalid outline, then there must be an outline
259 }
260 else
261 {
262 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
263 drcItem->SetErrorDetail( _( "(no edges found on Edge.Cuts layer)" ) );
264 drcItem->SetItems( m_board );
265
266 reportViolation( drcItem, m_board->GetBoundingBox().Centre(), Edge_Cuts );
267 }
268 }
269}
270
271
273{
274 const int progressDelta = 2000;
275 int ii = 0;
276 int items = 0;
277
278 auto countItems =
279 [&]( BOARD_ITEM* item ) -> bool
280 {
281 ++items;
282 return true;
283 };
284
285 LSET disabledLayers = LSET( m_board->GetEnabledLayers() ).flip();
286
287 // Perform the test only for copper layers
288 disabledLayers &= LSET::AllCuMask();
289
290 auto checkDisabledLayers =
291 [&]( BOARD_ITEM* item ) -> bool
292 {
293 if( m_drcEngine->IsErrorLimitExceeded( DRCE_DISABLED_LAYER_ITEM ) )
294 return false;
295
296 if( !reportProgress( ii++, items, progressDelta ) )
297 return false;
298
299 PCB_LAYER_ID badLayer = UNDEFINED_LAYER;
300
301 if( item->Type() == PCB_PAD_T )
302 {
303 PAD* pad = static_cast<PAD*>( item );
304
305 if( pad->GetAttribute() == PAD_ATTRIB::SMD
306 || pad->GetAttribute() == PAD_ATTRIB::CONN )
307 {
308 if( disabledLayers.test( pad->GetPrincipalLayer() ) )
309 badLayer = item->GetLayer();
310 }
311 else
312 {
313 // Through hole pad pierces all physical layers.
314 }
315 }
316 else if( item->Type() == PCB_VIA_T )
317 {
318 PCB_VIA* via = static_cast<PCB_VIA*>( item );
320 PCB_LAYER_ID bottom;
321
322 via->LayerPair( &top, &bottom );
323
324 if( disabledLayers.test( top ) )
325 badLayer = top;
326 else if( disabledLayers.test( bottom ) )
327 badLayer = bottom;
328 }
329 else if( item->Type() == PCB_ZONE_T )
330 {
331 // Footprint zones just get a top/bottom/inner setting, so they're on
332 // whatever inner layers there are.
333 }
334 else
335 {
336 LSET badLayers = disabledLayers & item->GetLayerSet();
337
338 if( badLayers.any() )
339 badLayer = badLayers.Seq().front();
340 }
341
342 if( badLayer != UNDEFINED_LAYER )
343 {
344 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_DISABLED_LAYER_ITEM );
345 drcItem->SetErrorDetail( wxString::Format( _( "(layer %s)" ), LayerName( badLayer ) ) );
346 drcItem->SetItems( item );
347
348 reportViolation( drcItem, item->GetPosition(), UNDEFINED_LAYER );
349 }
350
351 return true;
352 };
353
356}
357
358
360{
361 if( !m_drcEngine->HasRulesForConstraintType( ASSERTION_CONSTRAINT ) )
362 return;
363
364 std::vector<BOARD_ITEM*> allItems;
365
367 [&]( BOARD_ITEM* item ) -> bool
368 {
369 allItems.push_back( item );
370 return true;
371 } );
372
373 std::atomic<size_t> itemsDone( 0 );
374 size_t itemCount = allItems.size();
375
376 auto checkItem =
377 [&]( size_t idx )
378 {
379 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_ASSERTION_FAILURE )
380 && !m_drcEngine->IsCancelled() )
381 {
382 BOARD_ITEM* item = allItems[idx];
383
384 m_drcEngine->ProcessAssertions( item,
385 [&]( const DRC_CONSTRAINT* c )
386 {
387 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ASSERTION_FAILURE );
388 drcItem->SetErrorDetail( wxString::Format( wxS( "(%s)" ), c->GetName() ) );
389 drcItem->SetItems( item );
390 drcItem->SetViolatingRule( c->GetParentRule() );
391
392 reportViolation( drcItem, item->GetPosition(), item->GetLayer() );
393 } );
394 }
395
396 itemsDone.fetch_add( 1 );
397 };
398
400 auto itemFutures = tp.submit_loop( 0, itemCount, checkItem, itemCount );
401
402 while( itemsDone < itemCount )
403 {
404 reportProgress( itemsDone, itemCount );
405
406 if( m_drcEngine->IsCancelled() )
407 break;
408
409 itemFutures.wait_for( std::chrono::milliseconds( 250 ) );
410 }
411
412 // Join every worker before the captured locals go out of scope, whether we finished or
413 // were cancelled.
414 itemFutures.wait();
415}
416
417
419{
420 const int progressDelta = 2000;
421 int ii = 0;
422 int items = 0;
423
424 static const std::vector<KICAD_T> itemTypes = {
428 };
429
430 auto testAssertion =
431 [&]( BOARD_ITEM* item, const wxString& text, const VECTOR2I& pos, int layer )
432 {
433 static wxRegEx warningExpr( wxS( "^\\$\\{DRC_WARNING\\s*([^}]*)\\}(.*)$" ) );
434 static wxRegEx errorExpr( wxS( "^\\$\\{DRC_ERROR\\s*([^}]*)\\}(.*)$" ) );
435
436 if( warningExpr.Matches( text ) )
437 {
438 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_WARNING ) )
439 {
440 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_GENERIC_WARNING );
441 wxString drcText = warningExpr.GetMatch( text, 1 );
442
443 if( item )
444 drcItem->SetItems( item );
445 else
446 drcText += _( " (in drawing sheet)" );
447
448 drcItem->SetErrorMessage( drcText );
449
450 reportViolation( drcItem, pos, layer );
451 }
452
453 return true;
454 }
455
456 if( errorExpr.Matches( text ) )
457 {
458 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_ERROR ) )
459 {
460 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_GENERIC_ERROR );
461 wxString drcText = errorExpr.GetMatch( text, 1 );
462
463 if( item )
464 drcItem->SetItems( item );
465 else
466 drcText += _( " (in drawing sheet)" );
467
468 drcItem->SetErrorMessage( drcText );
469
470 reportViolation( drcItem, pos, layer );
471 }
472
473 return true;
474 }
475
476 return false;
477 };
478
480 [&]( BOARD_ITEM* item ) -> bool
481 {
482 ++items;
483 return true;
484 } );
485
487 [&]( BOARD_ITEM* item ) -> bool
488 {
489 if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
490 return false;
491
492 if( !reportProgress( ii++, items, progressDelta ) )
493 return false;
494
495 if( EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( item ) )
496 {
497 wxString result = ExpandEnvVarSubstitutions( textItem->GetShownText( true ),
498 nullptr /*project already done*/ );
499
500 if( result.Matches( wxT( "*${*}*" ) ) )
501 {
503 drcItem->SetItems( item );
504
505 reportViolation( drcItem, item->GetPosition(), item->GetLayer() );
506 }
507
508 testAssertion( item, textItem->GetText(), item->GetPosition(), item->GetLayer() );
509 }
510
511 return true;
512 } );
513
514 DS_PROXY_VIEW_ITEM* drawingSheet = m_drcEngine->GetDrawingSheet();
516
517 if( !drawingSheet || m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
518 return;
519
520 drawItems.SetPageNumber( wxT( "1" ) );
521 drawItems.SetSheetCount( 1 );
522 drawItems.SetFileName( wxT( "dummyFilename" ) );
523 drawItems.SetSheetName( wxT( "dummySheet" ) );
524 drawItems.SetSheetLayer( wxT( "dummyLayer" ) );
525 drawItems.SetProject( m_board->GetProject() );
526 drawItems.BuildDrawItemsList( drawingSheet->GetPageInfo(), drawingSheet->GetTitleBlock() );
527
528 for( DS_DRAW_ITEM_BASE* item = drawItems.GetFirst(); item; item = drawItems.GetNext() )
529 {
530 if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
531 break;
532
533 if( m_drcEngine->IsCancelled() )
534 return;
535
536 if( DS_DRAW_ITEM_TEXT* text = dynamic_cast<DS_DRAW_ITEM_TEXT*>( item ) )
537 {
538 if( testAssertion( nullptr, text->GetText(), text->GetPosition(), LAYER_DRAWINGSHEET ) )
539 {
540 // Don't run unresolved test
541 }
542 else if( text->GetShownText( true ).Matches( wxT( "*${*}*" ) ) )
543 {
544 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
545 drcItem->SetItems( drawingSheet );
546
547 reportViolation( drcItem, text->GetPosition(), LAYER_DRAWINGSHEET );
548 }
549 }
550 }
551}
552
553
555{
556 if( !m_board->GetProject() )
557 return;
558
559 std::shared_ptr<NET_SETTINGS> netSettings = m_board->GetProject()->GetProjectFile().NetSettings();
560 const std::shared_ptr<TUNING_PROFILES> tuningProfiles =
561 m_board->GetProject()->GetProjectFile().TuningProfileParameters();
562
563 std::set<wxString> profileNames;
564 std::ranges::for_each( tuningProfiles->GetTuningProfiles(),
565 [&profileNames]( const TUNING_PROFILE& tuningProfile )
566 {
567 if( const wxString name = tuningProfile.m_ProfileName; name != wxEmptyString )
568 profileNames.insert( name );
569 } );
570
571 for( const auto& [name, netclass] : netSettings->GetNetclasses() )
572 {
573 if( m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_TUNING_PROFILE ) )
574 return;
575
576 const wxString profileName = netclass->GetTuningProfile();
577
578 if( netclass->HasTuningProfile() && !profileNames.contains( profileName ) )
579 {
580 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_TUNING_PROFILE );
581 drcItem->SetErrorDetail( wxString::Format( "(Net Class: %s, Tuning Profile: %s)",
582 name,
583 profileName ) );
584
586 }
587 }
588}
589
590
592{
593 m_board = m_drcEngine->GetBoard();
594
595 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_INVALID_OUTLINE ) )
596 {
597 if( !reportPhase( _( "Checking board outline..." ) ) )
598 return false; // DRC cancelled
599
600 testOutline();
601 }
602
603 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_DISABLED_LAYER_ITEM ) )
604 {
605 if( !reportPhase( _( "Checking disabled layers..." ) ) )
606 return false; // DRC cancelled
607
609 }
610
611 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
612 {
613 if( !reportPhase( _( "Checking text variables..." ) ) )
614 return false; // DRC cancelled
615
616 testTextVars();
617 }
618
619 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_ASSERTION_FAILURE )
620 || !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_WARNING )
621 || !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_ERROR ) )
622 {
623 if( !reportPhase( _( "Checking assertions..." ) ) )
624 return false; // DRC cancelled
625
627 }
628
629 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_TUNING_PROFILE ) )
630 {
631 if( !reportPhase( _( "Checking for missing tuning profiles..." ) ) )
632 return false; // DRC cancelled
633
635 }
636
637 return !m_drcEngine->IsCancelled();
638}
639
640
641namespace detail
642{
644}
const char * name
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
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:81
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:265
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:372
constexpr BOX2< Vec > Intersect(const BOX2< Vec > &aRect)
Definition box2.h:343
constexpr size_type GetWidth() const
Definition box2.h:210
constexpr Vec Centre() const
Definition box2.h:93
constexpr size_type GetHeight() const
Definition box2.h:211
int GetCount() const
Return the number of objects in the list.
Definition collector.h:79
wxString GetName() const
Definition drc_rule.h:204
DRC_RULE * GetParentRule() const
Definition drc_rule.h:200
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition drc_item.cpp:417
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)
void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, const std::function< void(PCB_MARKER *)> &aPathGenerator=[](PCB_MARKER *){})
static std::vector< KICAD_T > s_allBasicItems
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:282
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:89
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition lset.cpp:604
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition lset.cpp:309
static const LSET & AllLayersMask()
Definition lset.cpp:637
Definition pad.h:61
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Make a set of SHAPE objects representing the PCB_SHAPE.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition pcb_shape.h:68
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
Definition collectors.h:517
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.
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:704
#define FOR_ERC_DRC
Expand '${var-name}' templates in text.
Definition common.h:95
bool BuildBoardPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, bool aInferOutlineIfNecessary, 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...
bool TestBoardOutlinesGraphicItems(BOARD *aBoard, int aMinDist, OUTLINE_ERROR_HANDLER *aErrorHandler)
Test a board graphic items on edge cut layer for validity.
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:68
@ DRCE_INVALID_OUTLINE
Definition drc_item.h:69
@ DRCE_GENERIC_ERROR
Definition drc_item.h:88
@ DRCE_MISSING_TUNING_PROFILE
Definition drc_item.h:112
@ DRCE_UNRESOLVED_VARIABLE
Definition drc_item.h:85
@ DRCE_ASSERTION_FAILURE
Definition drc_item.h:86
@ DRCE_GENERIC_WARNING
Definition drc_item.h:87
@ ASSERTION_CONSTRAINT
Definition drc_rule.h:84
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:274
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ Edge_Cuts
Definition layer_ids.h:108
@ UNDEFINED_LAYER
Definition layer_ids.h:57
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
@ SMD
Smd pad, appears on the solder paste layer (default)
Definition padstack.h:99
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
Definition padstack.h:100
Represents a single line in the tuning profile configuration grid.
KIBIS top(path, &reporter)
wxString result
Test unit parsing edge cases and error handling.
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
static thread_pool * tp
BS::priority_thread_pool thread_pool
Definition thread_pool.h:27
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:81
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:90
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:86
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition typeinfo.h:101
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:85
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:83
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
Definition typeinfo.h:88
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:80
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition typeinfo.h:93
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683