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 <set>
39#include <limits>
41#include <netclass.h>
45
46/*
47 Miscellaneous tests:
48
49 - DRCE_DISABLED_LAYER_ITEM, ///< item on a disabled layer
50 - DRCE_INVALID_OUTLINE, ///< invalid board outline
51 - DRCE_UNRESOLVED_VARIABLE,
52 - DRCE_ASSERTION_FAILURE, ///< user-defined assertions
53 - DRCE_GENERIC_WARNING ///< user-defined warnings, net classes that rules cannot name
54 - DRCE_GENERIC_ERROR ///< user-defined errors
55 - DRCE_MISSING_TUNING_PROFILES ///< tuning profile for netc lass not defined
56*/
57
58static void findClosestOutlineGap( BOARD* aBoard, PCB_SHAPE*& aItemA, PCB_SHAPE*& aItemB,
59 VECTOR2I& aMidpoint, int& aDistance )
60{
62 items.Collect( aBoard, { PCB_SHAPE_T } );
63
64 std::vector<PCB_SHAPE*> shapes;
65
66 for( int ii = 0; ii < items.GetCount(); ++ii )
67 {
68 PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( items[ii] );
69
70 if( shape->GetLayer() == Edge_Cuts )
71 shapes.push_back( shape );
72 }
73
74 int best = std::numeric_limits<int>::max();
75 VECTOR2I bestA;
76 VECTOR2I bestB;
77
78 for( size_t ii = 0; ii < shapes.size(); ++ii )
79 {
80 std::shared_ptr<SHAPE> shapeA = shapes[ii]->GetEffectiveShape();
81
82 for( size_t jj = ii + 1; jj < shapes.size(); ++jj )
83 {
84 std::shared_ptr<SHAPE> shapeB = shapes[jj]->GetEffectiveShape();
85 VECTOR2I ptA;
86 VECTOR2I ptB;
87
88 if( shapeA && shapeB && shapeA->NearestPoints( shapeB.get(), ptA, ptB ) )
89 {
90 int dist = ( ptA - ptB ).EuclideanNorm();
91
92 if( dist < best )
93 {
94 best = dist;
95 bestA = ptA;
96 bestB = ptB;
97 aItemA = shapes[ii];
98 aItemB = shapes[jj];
99 }
100 }
101 }
102 }
103
104 if( aItemA && aItemB )
105 {
106 aDistance = best;
107 aMidpoint = ( bestA + bestB ) / 2;
108 }
109 else
110 {
111 aDistance = 0;
112 aMidpoint = VECTOR2I();
113 }
114}
115
117{
118public:
120 m_board( nullptr )
121 {
122 m_isRuleDriven = false;
123 }
124
125 virtual ~DRC_TEST_PROVIDER_MISC() = default;
126
127 virtual bool Run() override;
128
129 virtual const wxString GetName() const override { return wxT( "miscellaneous" ); };
130
131private:
132 void testOutline();
133 void testDisabledLayers();
134 void testTextVars();
135 void testAssertions();
138
140};
141
142
144{
145 SHAPE_POLY_SET dummyOutline;
146 bool errorHandled = false;
147
148 OUTLINE_ERROR_HANDLER errorHandler =
149 [&]( const wxString& msg, BOARD_ITEM* itemA, BOARD_ITEM* itemB, const VECTOR2I& pt )
150 {
151 errorHandled = true;
152
153 if( m_drcEngine->IsErrorLimitExceeded( DRCE_INVALID_OUTLINE ) )
154 return;
155
156 if( !itemA )
157 std::swap( itemA, itemB );
158
159 VECTOR2I markerPos = pt;
160 int gap = 0;
161 PCB_SHAPE* shapeA = nullptr;
162 PCB_SHAPE* shapeB = nullptr;
163 bool usedGap = false;
164
165 if( itemA && itemB && itemA->Type() == PCB_SHAPE_T && itemB->Type() == PCB_SHAPE_T )
166 {
167 shapeA = static_cast<PCB_SHAPE*>( itemA );
168 shapeB = static_cast<PCB_SHAPE*>( itemB );
169 }
170 else if( itemA && !itemB && itemA->Type() == PCB_SHAPE_T )
171 {
172 // A single item was flagged (e.g. a degenerate shape). Keep the marker
173 // at that item so the user can locate the bad geometry.
174 shapeA = static_cast<PCB_SHAPE*>( itemA );
175 }
176 else
177 {
178 // No usable item pair identified. Look for the most likely culprits.
179 findClosestOutlineGap( m_board, shapeA, shapeB, markerPos, gap );
180 itemA = shapeA;
181 itemB = shapeB;
182 usedGap = shapeA && shapeB;
183 }
184
185 if( shapeA && shapeB )
186 {
187 std::shared_ptr<SHAPE> effectiveShapeA = shapeA->GetEffectiveShape();
188 std::shared_ptr<SHAPE> effectiveShapeB = shapeB->GetEffectiveShape();
189
190 if( effectiveShapeA && effectiveShapeB )
191 {
192 BOX2I bboxA = effectiveShapeA->BBox();
193 BOX2I bboxB = effectiveShapeB->BBox();
194 BOX2I overlap = bboxA.Intersect( bboxB );
195
196 if( overlap.GetWidth() > 0 && overlap.GetHeight() > 0 )
197 {
198 markerPos = overlap.Centre();
199 usedGap = false;
200 }
201 else
202 {
203 VECTOR2I ptA, ptB;
204
205 if( effectiveShapeA->NearestPoints( effectiveShapeB.get(), ptA, ptB ) )
206 {
207 gap = ( ptA - ptB ).EuclideanNorm();
208 markerPos = ( ptA + ptB ) / 2;
209 usedGap = true;
210 }
211 }
212 }
213 }
214
215 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
216
217 if( itemA && itemB && usedGap )
218 {
219 drcItem->SetErrorDetail( wxString::Format( _( "%s (gap %s)" ), msg, MessageTextFromValue( gap ) ) );
220 }
221 else
222 {
223 drcItem->SetErrorDetail( msg );
224 }
225
226 drcItem->SetItems( itemA, itemB );
227
228 reportViolation( drcItem, markerPos, Edge_Cuts );
229 };
230
231 // Test for very small graphic items (a few nm size) that can create issues
232 // when trying to build the board outlines, and they are not easy to locate on screen.
233 const int minSizeForValideGraphics = pcbIUScale.mmToIU( 0.001 );
234
235 if( !TestBoardOutlinesGraphicItems(m_board, minSizeForValideGraphics, &errorHandler ) )
236 {
237 if( errorHandled )
238 {
239 // if there are invalid items on Edge.Cuts, they are already reported
240 }
241 else
242 {
243 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
244 drcItem->SetErrorDetail( _( "(Suspicious items found on Edge.Cuts layer)" ) );
245 drcItem->SetItems( m_board );
246
247 reportViolation( drcItem, m_board->GetBoundingBox().Centre(), Edge_Cuts );
248 }
249 }
250
251
252 // Use the standard chaining epsilon here so that we report errors that might affect
253 // other tools (such as 3D viewer).
254 int chainingEpsilon = m_board->GetOutlinesChainingEpsilon();
255
256 // Arc to segment approximation error (not critical here: we do not use the outline shape):
257 int maxError = pcbIUScale.mmToIU( 0.05 );
258
259 if( !BuildBoardPolygonOutlines( m_board, dummyOutline, maxError, chainingEpsilon, true, &errorHandler ) )
260 {
261 if( errorHandled )
262 {
263 // if there is an invalid outline, then there must be an outline
264 }
265 else
266 {
267 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
268 drcItem->SetErrorDetail( _( "(no edges found on Edge.Cuts layer)" ) );
269 drcItem->SetItems( m_board );
270
271 reportViolation( drcItem, m_board->GetBoundingBox().Centre(), Edge_Cuts );
272 }
273 }
274}
275
276
278{
279 const int progressDelta = 2000;
280 int ii = 0;
281 int items = 0;
282
283 auto countItems =
284 [&]( BOARD_ITEM* item ) -> bool
285 {
286 ++items;
287 return true;
288 };
289
290 LSET disabledLayers = LSET( m_board->GetEnabledLayers() ).flip();
291
292 // Perform the test only for copper layers
293 disabledLayers &= LSET::AllCuMask();
294
295 auto checkDisabledLayers =
296 [&]( BOARD_ITEM* item ) -> bool
297 {
298 if( m_drcEngine->IsErrorLimitExceeded( DRCE_DISABLED_LAYER_ITEM ) )
299 return false;
300
301 if( !reportProgress( ii++, items, progressDelta ) )
302 return false;
303
304 PCB_LAYER_ID badLayer = UNDEFINED_LAYER;
305
306 if( item->Type() == PCB_PAD_T )
307 {
308 PAD* pad = static_cast<PAD*>( item );
309
310 if( pad->GetAttribute() == PAD_ATTRIB::SMD
311 || pad->GetAttribute() == PAD_ATTRIB::CONN )
312 {
313 if( disabledLayers.Contains( pad->GetPrincipalLayer() ) )
314 badLayer = item->GetLayer();
315 }
316 else
317 {
318 // Through hole pad pierces all physical layers.
319 }
320 }
321 else if( item->Type() == PCB_VIA_T )
322 {
323 PCB_VIA* via = static_cast<PCB_VIA*>( item );
325 PCB_LAYER_ID bottom;
326
327 via->LayerPair( &top, &bottom );
328
329 if( disabledLayers.test( top ) )
330 badLayer = top;
331 else if( disabledLayers.test( bottom ) )
332 badLayer = bottom;
333 }
334 else if( item->Type() == PCB_ZONE_T )
335 {
336 // Footprint zones just get a top/bottom/inner setting, so they're on
337 // whatever inner layers there are.
338 }
339 else
340 {
341 LSET badLayers = disabledLayers & item->GetLayerSet();
342
343 if( badLayers.any() )
344 badLayer = badLayers.Seq().front();
345 }
346
347 if( badLayer != UNDEFINED_LAYER )
348 {
349 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_DISABLED_LAYER_ITEM );
350 drcItem->SetErrorDetail( wxString::Format( _( "(layer %s)" ), LayerName( badLayer ) ) );
351 drcItem->SetItems( item );
352
353 reportViolation( drcItem, item->GetPosition(), UNDEFINED_LAYER );
354 }
355
356 return true;
357 };
358
361}
362
363
365{
366 if( !m_drcEngine->HasRulesForConstraintType( ASSERTION_CONSTRAINT ) )
367 return;
368
369 std::vector<BOARD_ITEM*> allItems;
370
372 [&]( BOARD_ITEM* item ) -> bool
373 {
374 allItems.push_back( item );
375 return true;
376 } );
377
378 std::atomic<size_t> itemsDone( 0 );
379 size_t itemCount = allItems.size();
380
381 auto checkItem =
382 [&]( size_t idx )
383 {
384 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_ASSERTION_FAILURE )
385 && !m_drcEngine->IsCancelled() )
386 {
387 BOARD_ITEM* item = allItems[idx];
388
389 m_drcEngine->ProcessAssertions( item,
390 [&]( const DRC_CONSTRAINT* c )
391 {
392 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ASSERTION_FAILURE );
393 drcItem->SetErrorDetail( wxString::Format( wxS( "(%s)" ), c->GetName() ) );
394 drcItem->SetItems( item );
395 drcItem->SetViolatingRule( c->GetParentRule() );
396
397 reportViolation( drcItem, item->GetPosition(), item->GetLayer() );
398 } );
399 }
400
401 itemsDone.fetch_add( 1 );
402 };
403
405 auto itemFutures = tp.submit_loop( 0, itemCount, checkItem, itemCount );
406
407 while( itemsDone < itemCount )
408 {
409 reportProgress( itemsDone, itemCount );
410
411 if( m_drcEngine->IsCancelled() )
412 break;
413
414 itemFutures.wait_for( std::chrono::milliseconds( 250 ) );
415 }
416
417 // Join every worker before the captured locals go out of scope, whether we finished or
418 // were cancelled.
419 itemFutures.wait();
420}
421
422
424{
425 const int progressDelta = 2000;
426 int ii = 0;
427 int items = 0;
428
429 static const std::vector<KICAD_T> itemTypes = {
433 };
434
435 // The leading "(^|[^\\\\])" group requires the marker to start the string or follow a non-backslash,
436 // so `\${ERC_ERROR ...}` stays inert. (The group is just to make it easier for a human to parse.)
437 static wxRegEx varRefRegEx( wxT( "(^|[^\\\\])\\$\\{.*\\}.*" ) );
438
439 auto testAssertion =
440 [&]( BOARD_ITEM* item, const wxString& text, const VECTOR2I& pos, int layer )
441 {
442 // Match anywhere in the text so users can embed ${DRC_ERROR ...}
443 // or ${DRC_WARNING ...} inside placeholder strings rather than
444 // only at the start of the field. The leading "(^|[^\\\\])"
445 // group requires the marker to start the string or follow a
446 // non-backslash, so `\${DRC_ERROR ...}` stays inert; the
447 // captured message is group 2.
448 static wxRegEx warningExpr( wxS( "(^|[^\\\\])\\$\\{DRC_WARNING\\s*([^}]*)\\}" ) );
449 static wxRegEx errorExpr( wxS( "(^|[^\\\\])\\$\\{DRC_ERROR\\s*([^}]*)\\}" ) );
450
451 auto reportEach =
452 [&]( wxRegEx& aExpr, int aErrorCode )
453 {
454 // Return true if any token of this kind was *matched*, even when
455 // the per-code error limit had already been exceeded. The caller
456 // uses the return value to suppress an unrelated
457 // DRCE_UNRESOLVED_VARIABLE marker; if we let the limit-exceeded
458 // case fall through to false we'd raise the wrong error.
459 bool found = false;
460 wxString remaining = text;
461
462 while( aExpr.Matches( remaining ) )
463 {
464 found = true;
465
466 if( !m_drcEngine->IsErrorLimitExceeded( aErrorCode ) )
467 {
468 wxString drcText = aExpr.GetMatch( remaining, 2 );
469
470 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( aErrorCode );
471
472 if( item )
473 drcItem->SetItems( item );
474 else
475 drcText += _( " (in drawing sheet)" );
476
477 drcItem->SetErrorMessage( drcText );
478
479 reportViolation( drcItem, pos, layer );
480 }
481
482 size_t start = 0;
483 size_t len = 0;
484
485 if( !aExpr.GetMatch( &start, &len, 0 ) || len == 0 )
486 break;
487
488 remaining = remaining.Mid( start + len );
489 }
490
491 return found;
492 };
493
494 bool foundWarning = reportEach( warningExpr, DRCE_GENERIC_WARNING );
495 bool foundError = reportEach( errorExpr, DRCE_GENERIC_ERROR );
496
497 return foundWarning || foundError;
498 };
499
501 [&]( BOARD_ITEM* item ) -> bool
502 {
503 ++items;
504 return true;
505 } );
506
508 [&]( BOARD_ITEM* item ) -> bool
509 {
510 if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
511 return false;
512
513 if( !reportProgress( ii++, items, progressDelta ) )
514 return false;
515
516 if( EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( item ) )
517 {
518 // A matched ${DRC_ERROR}/${DRC_WARNING} is the intended signal; the resolved
519 // text still carries a literal ${...}, so flag the unresolved variable only
520 // when no marker fired (matching the drawing-sheet path below).
521 if( testAssertion( item, textItem->GetText(), item->GetPosition(), item->GetLayer() ) )
522 {
523 // Skip unresolved-variable test.
524 // Yes, the assertion message could have an unresolved variable in it, but it's
525 // going to end up in the DRC window anyway, so there's not much sense in double-
526 // reporting it.
527 }
528 else if( varRefRegEx.Matches( ExpandEnvVarSubstitutions( textItem->GetShownText( FOR_ERC_DRC ),
529 nullptr /*project already done*/ ) ) )
530 {
531 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
532 drcItem->SetItems( item );
533
534 reportViolation( drcItem, item->GetPosition(), item->GetLayer() );
535 }
536 }
537
538 return true;
539 } );
540
541 DS_PROXY_VIEW_ITEM* drawingSheet = m_drcEngine->GetDrawingSheet();
543
544 if( !drawingSheet || m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
545 return;
546
547 drawItems.SetPageNumber( wxT( "1" ) );
548 drawItems.SetSheetCount( 1 );
549 drawItems.SetFileName( wxT( "dummyFilename" ) );
550 drawItems.SetSheetName( wxT( "dummySheet" ) );
551 drawItems.SetSheetLayer( wxT( "dummyLayer" ) );
552 drawItems.SetProject( m_board->GetProject() );
553 drawItems.BuildDrawItemsList( drawingSheet->GetPageInfo(), drawingSheet->GetTitleBlock() );
554
555 for( DS_DRAW_ITEM_BASE* item = drawItems.GetFirst(); item; item = drawItems.GetNext() )
556 {
557 if( m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
558 break;
559
560 if( m_drcEngine->IsCancelled() )
561 return;
562
563 if( DS_DRAW_ITEM_TEXT* text = dynamic_cast<DS_DRAW_ITEM_TEXT*>( item ) )
564 {
565 if( testAssertion( nullptr, text->GetText(), text->GetPosition(), LAYER_DRAWINGSHEET ) )
566 {
567 // Don't run unresolved test
568 }
569 else if( varRefRegEx.Matches( text->GetShownText( FOR_ERC_DRC ) ) )
570 {
571 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
572 drcItem->SetItems( drawingSheet );
573
574 reportViolation( drcItem, text->GetPosition(), LAYER_DRAWINGSHEET );
575 }
576 }
577 }
578}
579
580
582{
583 if( !m_board->GetProject() )
584 return;
585
586 std::shared_ptr<NET_SETTINGS> netSettings = m_board->GetProject()->GetProjectFile().NetSettings();
587 const std::shared_ptr<TUNING_PROFILES> tuningProfiles =
588 m_board->GetProject()->GetProjectFile().TuningProfileParameters();
589
590 std::set<wxString> profileNames;
591 std::ranges::for_each( tuningProfiles->GetTuningProfiles(),
592 [&profileNames]( const TUNING_PROFILE& tuningProfile )
593 {
594 if( const wxString name = tuningProfile.m_ProfileName; name != wxEmptyString )
595 profileNames.insert( name );
596 } );
597
598 for( const auto& [name, netclass] : netSettings->GetNetclasses() )
599 {
600 if( m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_TUNING_PROFILE ) )
601 return;
602
603 const wxString profileName = netclass->GetTuningProfile();
604
605 if( netclass->HasTuningProfile() && !profileNames.contains( profileName ) )
606 {
607 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_TUNING_PROFILE );
608 drcItem->SetErrorDetail( wxString::Format( "(Net Class: %s, Tuning Profile: %s)",
609 name,
610 profileName ) );
611
613 }
614 }
615}
616
617
619{
620 std::shared_ptr<NET_SETTINGS> netSettings = m_board->GetDesignSettings().m_NetSettings;
621 std::set<wxString> names = { netSettings->GetDefaultNetclass()->GetName() };
622
623 for( const auto& [name, netclass] : netSettings->GetNetclasses() )
624 names.insert( netclass->GetName() );
625
626 // A label can assign a class nobody declared, so name the parts of a composite DRC_ENGINE dropped
627 for( const auto& [name, netclass] : netSettings->GetCompositeNetclasses() )
628 {
629 if( LIBEVAL::EscapeStringLiteral( netclass->GetName() ) )
630 continue;
631
632 for( const NETCLASS* constituent : netclass->GetConstituentNetclasses() )
633 names.insert( constituent->GetName() );
634 }
635
636 for( const wxString& name : names )
637 {
638 if( m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_WARNING ) )
639 return;
640
641 // DRC_ENGINE drops the implicit rules of such a class, so its limits would go unchecked without a word
643 {
644 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_GENERIC_WARNING );
645 drcItem->SetErrorMessage( wxString::Format( _( "Net class '%s' cannot be used in rules; its clearance "
646 "and width are not checked" ),
647 name ) );
648
650 }
651 }
652}
653
654
656{
657 m_board = m_drcEngine->GetBoard();
658
659 // Ahead of the text variable checks, which share the generic warning limit
660 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_WARNING ) )
661 {
662 if( !reportPhase( _( "Checking net class names..." ) ) )
663 return false; // DRC cancelled
664
666 }
667
668 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_INVALID_OUTLINE ) )
669 {
670 if( !reportPhase( _( "Checking board outline..." ) ) )
671 return false; // DRC cancelled
672
673 testOutline();
674 }
675
676 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_DISABLED_LAYER_ITEM ) )
677 {
678 if( !reportPhase( _( "Checking disabled layers..." ) ) )
679 return false; // DRC cancelled
680
682 }
683
684 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
685 {
686 if( !reportPhase( _( "Checking text variables..." ) ) )
687 return false; // DRC cancelled
688
689 testTextVars();
690 }
691
692 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_ASSERTION_FAILURE )
693 || !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_WARNING )
694 || !m_drcEngine->IsErrorLimitExceeded( DRCE_GENERIC_ERROR ) )
695 {
696 if( !reportPhase( _( "Checking assertions..." ) ) )
697 return false; // DRC cancelled
698
700 }
701
702 if( !m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_TUNING_PROFILE ) )
703 {
704 if( !reportPhase( _( "Checking for missing tuning profiles..." ) ) )
705 return false; // DRC cancelled
706
708 }
709
710 return !m_drcEngine->IsCancelled();
711}
712
713
714namespace detail
715{
717}
const char * name
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:128
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
BASE_SET & flip(size_t pos)
Definition base_set.h:170
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:85
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:411
constexpr BOX2< Vec > Intersect(const BOX2< Vec > &aRect)
Definition box2.h:344
constexpr size_type GetWidth() const
Definition box2.h:211
constexpr Vec Centre() const
Definition box2.h:94
constexpr size_type GetHeight() const
Definition box2.h:212
int GetCount() const
Return the number of objects in the list.
Definition collector.h:79
wxString GetName() const
Definition drc_rule.h:162
DRC_RULE * GetParentRule() const
Definition drc_rule.h:147
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition drc_item.cpp:492
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:348
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
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
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
Definition lset.h:63
A collection of nets and the parameters used to route or test these nets.
Definition netclass.h:44
const std::vector< NETCLASS * > & GetConstituentNetclasses() const
Gets the netclasses which make up this netclass.
Definition netclass.cpp:312
Definition pad.h:61
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) 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:70
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
Definition collectors.h:518
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, bool aAllowEscapes)
Replace any environment variable & text variable references with their values.
Definition common.cpp:777
@ FOR_ERC_DRC
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
@ ASSERTION_CONSTRAINT
@ DRCE_DISABLED_LAYER_ITEM
Definition drc_item.h:85
@ DRCE_INVALID_OUTLINE
Definition drc_item.h:86
@ DRCE_GENERIC_ERROR
Definition drc_item.h:105
@ DRCE_MISSING_TUNING_PROFILE
Definition drc_item.h:130
@ DRCE_UNRESOLVED_VARIABLE
Definition drc_item.h:102
@ DRCE_ASSERTION_FAILURE
Definition drc_item.h:103
@ DRCE_GENERIC_WARNING
Definition drc_item.h:104
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
std::optional< wxString > EscapeStringLiteral(const wxString &aText)
Escape text for use between the quotes of an expression string.
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
@ SMD
Smd pad, appears on the solder paste layer (default)
Definition padstack.h:98
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
Definition padstack.h:99
Represents a single line in the tuning profile configuration grid.
KIBIS top(path, &reporter)
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:80
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:89
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:85
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition typeinfo.h:100
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:84
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition typeinfo.h:82
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
Definition typeinfo.h:87
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:79
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition typeinfo.h:92
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708