KiCad PCB EDA Suite
drc.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-2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com
6  * Copyright (C) 2017-2018 KiCad Developers, see change_log.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
30 #include <fctsys.h>
31 #include <pcb_edit_frame.h>
32 #include <trigo.h>
33 #include <base_units.h>
34 #include <board_design_settings.h>
35 
36 #include <class_module.h>
37 #include <class_track.h>
38 #include <class_pad.h>
39 #include <class_zone.h>
40 #include <class_pcb_text.h>
41 #include <class_draw_panel_gal.h>
42 #include <view/view.h>
43 #include <geometry/seg.h>
44 #include <math_for_graphics.h>
45 
46 #include <connectivity_data.h>
47 #include <connectivity_algo.h>
48 
49 #include <tool/tool_manager.h>
50 #include <tools/pcb_actions.h>
51 
52 #include <pcbnew.h>
53 #include <drc.h>
54 
55 #include <dialog_drc.h>
56 #include <wx/progdlg.h>
57 #include <board_commit.h>
58 
59 void DRC::ShowDRCDialog( wxWindow* aParent )
60 {
61  bool show_dlg_modal = true;
62 
63  // the dialog needs a parent frame. if it is not specified, this is
64  // the PCB editor frame specified in DRC class.
65  if( aParent == NULL )
66  {
67  // if any parent is specified, the dialog is modal.
68  // if this is the default PCB editor frame, it is not modal
69  show_dlg_modal = false;
70  aParent = m_pcbEditorFrame;
71  }
72 
74  toolMgr->RunAction( ACTIONS::cancelInteractive, true );
75  toolMgr->DeactivateTool();
76  toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
77 
78  if( !m_drcDialog )
79  {
80  m_drcDialog = new DIALOG_DRC_CONTROL( this, m_pcbEditorFrame, aParent );
82 
84 
85  if( show_dlg_modal )
86  m_drcDialog->ShowModal();
87  else
88  m_drcDialog->Show( true );
89  }
90  else // The dialog is just not visible (because the user has double clicked on an error item)
91  {
93  m_drcDialog->Show( true );
94  }
95 }
96 
97 
99 {
100  // In legacy routing mode, do not add markers to the board.
101  // only shows the drc error message
103  {
104  m_pcbEditorFrame->SetMsgPanel( aMarker );
105  delete aMarker;
106  m_currentMarker = nullptr;
107  }
108  else
109  {
110  BOARD_COMMIT commit( m_pcbEditorFrame );
111  commit.Add( aMarker );
112  commit.Push( wxEmptyString, false, false );
113  }
114 }
115 
116 
117 void DRC::DestroyDRCDialog( int aReason )
118 {
119  if( m_drcDialog )
120  {
121  if( aReason == wxID_OK )
122  {
123  // if user clicked OK, save his choices in this DRC object.
125  }
126 
127  m_drcDialog->Destroy();
128  m_drcDialog = NULL;
129  }
130 }
131 
132 
133 DRC::DRC( PCB_EDIT_FRAME* aPcbWindow )
134 {
135  m_pcbEditorFrame = aPcbWindow;
136  m_pcb = aPcbWindow->GetBoard();
137  m_drcDialog = NULL;
138 
139  // establish initial values for everything:
140  m_drcInLegacyRoutingMode = false;
141  m_doPad2PadTest = true; // enable pad to pad clearance tests
142  m_doUnconnectedTest = true; // enable unconnected tests
143  m_doZonesTest = true; // enable zone to items clearance tests
144  m_doKeepoutTest = true; // enable keepout areas to items clearance tests
145  m_doFootprintOverlapping = true; // enable courtyards areas overlap tests
146  m_doNoCourtyardDefined = true; // enable missing courtyard in footprint warning
147  m_abortDRC = false;
148  m_drcInProgress = false;
149  m_refillZones = false; // Only fill zones if requested by user.
150  m_reportAllTrackErrors = false;
151  m_doCreateRptFile = false;
152 
153  // m_rptFilename set to empty by its constructor
154 
155  m_currentMarker = NULL;
156 
157  m_segmAngle = 0;
158  m_segmLength = 0;
159 
160  m_xcliplo = 0;
161  m_ycliplo = 0;
162  m_xcliphi = 0;
163  m_ycliphi = 0;
164 }
165 
166 
168 {
169  // maybe someday look at pointainer.h <- google for "pointainer.h"
170  for( unsigned i = 0; i<m_unconnected.size(); ++i )
171  delete m_unconnected[i];
172 }
173 
174 
175 int DRC::DrcOnCreatingTrack( TRACK* aRefSegm, TRACK* aList )
176 {
177  updatePointers();
178 
179  // Set right options for this on line drc
180  int drc_state = m_drcInLegacyRoutingMode;
182  int rpt_state = m_reportAllTrackErrors;
183  m_reportAllTrackErrors = false;
184 
185  if( !doTrackDrc( aRefSegm, aList, true ) )
186  {
187  if( m_currentMarker )
189 
190  m_drcInLegacyRoutingMode = drc_state;
191  m_reportAllTrackErrors = rpt_state;
192  return BAD_DRC;
193  }
194 
195  if( !doTrackKeepoutDrc( aRefSegm ) )
196  {
197  wxASSERT( m_currentMarker );
198 
200  delete m_currentMarker;
201  m_currentMarker = nullptr;
202  m_drcInLegacyRoutingMode = drc_state;
203  m_reportAllTrackErrors = rpt_state;
204  return BAD_DRC;
205  }
206 
207  m_drcInLegacyRoutingMode = drc_state;
208  m_reportAllTrackErrors = rpt_state;
209  return OK_DRC;
210 }
211 
212 
213 int DRC::TestZoneToZoneOutline( ZONE_CONTAINER* aZone, bool aCreateMarkers )
214 {
215  BOARD* board = m_pcbEditorFrame->GetBoard();
216  BOARD_COMMIT commit( m_pcbEditorFrame );
217  int nerrors = 0;
218 
219  // iterate through all areas
220  for( int ia = 0; ia < board->GetAreaCount(); ia++ )
221  {
222  ZONE_CONTAINER* zoneRef = board->GetArea( ia );
223  SHAPE_POLY_SET refSmoothedPoly;
224 
225  zoneRef->BuildSmoothedPoly( refSmoothedPoly );
226 
227  if( !zoneRef->IsOnCopperLayer() )
228  continue;
229 
230  // When testing only a single area, skip all others
231  if( aZone && ( aZone != zoneRef) )
232  continue;
233 
234  for( int ia2 = 0; ia2 < board->GetAreaCount(); ia2++ )
235  {
236  ZONE_CONTAINER* zoneToTest = board->GetArea( ia2 );
237  SHAPE_POLY_SET testSmoothedPoly;
238 
239  zoneToTest->BuildSmoothedPoly( testSmoothedPoly );
240 
241  if( zoneRef == zoneToTest )
242  continue;
243 
244  // test for same layer
245  if( zoneRef->GetLayer() != zoneToTest->GetLayer() )
246  continue;
247 
248  // Test for same net
249  if( zoneRef->GetNetCode() == zoneToTest->GetNetCode() && zoneRef->GetNetCode() >= 0 )
250  continue;
251 
252  // test for different priorities
253  if( zoneRef->GetPriority() != zoneToTest->GetPriority() )
254  continue;
255 
256  // test for different types
257  if( zoneRef->GetIsKeepout() != zoneToTest->GetIsKeepout() )
258  continue;
259 
260  // Examine a candidate zone: compare zoneToTest to zoneRef
261 
262  // Get clearance used in zone to zone test. The policy used to
263  // obtain that value is now part of the zone object itself by way of
264  // ZONE_CONTAINER::GetClearance().
265  int zone2zoneClearance = zoneRef->GetClearance( zoneToTest );
266 
267  // Keepout areas have no clearance, so set zone2zoneClearance to 1
268  // ( zone2zoneClearance = 0 can create problems in test functions)
269  if( zoneRef->GetIsKeepout() )
270  zone2zoneClearance = 1;
271 
272  // test for some corners of zoneRef inside zoneToTest
273  for( auto iterator = refSmoothedPoly.IterateWithHoles(); iterator; iterator++ )
274  {
275  VECTOR2I currentVertex = *iterator;
276 
277  if( testSmoothedPoly.Contains( currentVertex ) )
278  {
279  // COPPERAREA_COPPERAREA error: copper area ref corner inside copper area
280  if( aCreateMarkers )
281  {
282  wxPoint pt( currentVertex.x, currentVertex.y );
283  wxString msg1 = zoneRef->GetSelectMenuText();
284  wxString msg2 = zoneToTest->GetSelectMenuText();
286  pt, msg1, pt, msg2, pt );
287  commit.Add( marker );
288  }
289 
290  nerrors++;
291  }
292  }
293 
294  // test for some corners of zoneToTest inside zoneRef
295  for( auto iterator = testSmoothedPoly.IterateWithHoles(); iterator; iterator++ )
296  {
297  VECTOR2I currentVertex = *iterator;
298 
299  if( refSmoothedPoly.Contains( currentVertex ) )
300  {
301  // COPPERAREA_COPPERAREA error: copper area corner inside copper area ref
302  if( aCreateMarkers )
303  {
304  wxPoint pt( currentVertex.x, currentVertex.y );
305  wxString msg1 = zoneToTest->GetSelectMenuText();
306  wxString msg2 = zoneRef->GetSelectMenuText();
308  pt, msg1, pt, msg2, pt );
309  commit.Add( marker );
310  }
311 
312  nerrors++;
313  }
314  }
315 
316  // Iterate through all the segments of refSmoothedPoly
317  for( auto refIt = refSmoothedPoly.IterateSegmentsWithHoles(); refIt; refIt++ )
318  {
319  // Build ref segment
320  SEG refSegment = *refIt;
321 
322  // Iterate through all the segments in testSmoothedPoly
323  for( auto testIt = testSmoothedPoly.IterateSegmentsWithHoles(); testIt; testIt++ )
324  {
325  // Build test segment
326  SEG testSegment = *testIt;
327  wxPoint pt;
328 
329  int ax1, ay1, ax2, ay2;
330  ax1 = refSegment.A.x;
331  ay1 = refSegment.A.y;
332  ax2 = refSegment.B.x;
333  ay2 = refSegment.B.y;
334 
335  int bx1, by1, bx2, by2;
336  bx1 = testSegment.A.x;
337  by1 = testSegment.A.y;
338  bx2 = testSegment.B.x;
339  by2 = testSegment.B.y;
340 
341  int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
342  0,
343  ax1, ay1, ax2, ay2,
344  0,
345  zone2zoneClearance,
346  &pt.x, &pt.y );
347 
348  if( d < zone2zoneClearance )
349  {
350  // COPPERAREA_COPPERAREA error : intersect or too close
351  if( aCreateMarkers )
352  {
353  wxString msg1 = zoneRef->GetSelectMenuText();
354  wxString msg2 = zoneToTest->GetSelectMenuText();
356  pt, msg1, pt, msg2, pt );
357  commit.Add( marker );
358  }
359 
360  nerrors++;
361  }
362  }
363  }
364  }
365  }
366 
367  if( aCreateMarkers )
368  commit.Push( wxEmptyString, false, false );
369 
370  return nerrors;
371 }
372 
373 
374 int DRC::DrcOnCreatingZone( ZONE_CONTAINER* aArea, int aCornerIndex )
375 {
376  updatePointers();
377 
378  // Set right options for this on line drc
379  int drc_state = m_drcInLegacyRoutingMode;
381  int rpt_state = m_reportAllTrackErrors;
382  m_reportAllTrackErrors = false;
383 
384  if( !doEdgeZoneDrc( aArea, aCornerIndex ) )
385  {
386  wxASSERT( m_currentMarker );
388  delete m_currentMarker;
389  m_currentMarker = nullptr;
390  m_drcInLegacyRoutingMode = drc_state;
391  m_reportAllTrackErrors = rpt_state;
392  return BAD_DRC;
393  }
394 
395  m_drcInLegacyRoutingMode = drc_state;
396  m_reportAllTrackErrors = rpt_state;
397  return OK_DRC;
398 }
399 
400 
401 void DRC::RunTests( wxTextCtrl* aMessages )
402 {
403  // be sure m_pcb is the current board, not a old one
404  // ( the board can be reloaded )
406 
407  // someone should have cleared the two lists before calling this.
408 
409  if( !testNetClasses() )
410  {
411  // testing the netclasses is a special case because if the netclasses
412  // do not pass the BOARD_DESIGN_SETTINGS checks, then every member of a net
413  // class (a NET) will cause its items such as tracks, vias, and pads
414  // to also fail. So quit after *all* netclass errors have been reported.
415  if( aMessages )
416  aMessages->AppendText( _( "Aborting\n" ) );
417 
418  // update the m_drcDialog listboxes
419  updatePointers();
420 
421  return;
422  }
423 
424  // test pad to pad clearances, nothing to do with tracks, vias or zones.
425  if( m_doPad2PadTest )
426  {
427  if( aMessages )
428  {
429  aMessages->AppendText( _( "Pad clearances...\n" ) );
430  wxSafeYield();
431  }
432 
433  testPad2Pad();
434  }
435 
436  // test track and via clearances to other tracks, pads, and vias
437  if( aMessages )
438  {
439  aMessages->AppendText( _( "Track clearances...\n" ) );
440  wxSafeYield();
441  }
442 
443  testTracks( aMessages ? aMessages->GetParent() : m_pcbEditorFrame, true );
444 
445  // caller (a wxTopLevelFrame) is the wxDialog or the Pcb Editor frame that call DRC:
446  wxWindow* caller = aMessages ? aMessages->GetParent() : m_pcbEditorFrame;
447 
448  if( m_refillZones )
449  {
450  if( aMessages )
451  aMessages->AppendText( _( "Refilling all zones...\n" ) );
452 
453  m_pcbEditorFrame->Fill_All_Zones( caller );
454  }
455  else
456  {
457  if( aMessages )
458  aMessages->AppendText( _( "Checking zone fills...\n" ) );
459 
461  }
462 
463  // test zone clearances to other zones
464  if( aMessages )
465  {
466  aMessages->AppendText( _( "Zone to zone clearances...\n" ) );
467  wxSafeYield();
468  }
469 
470  testZones();
471 
472  // find and gather unconnected pads.
473  if( m_doUnconnectedTest )
474  {
475  if( aMessages )
476  {
477  aMessages->AppendText( _( "Unconnected pads...\n" ) );
478  aMessages->Refresh();
479  }
480 
481  testUnconnected();
482  }
483 
484  // find and gather vias, tracks, pads inside keepout areas.
485  if( m_doKeepoutTest )
486  {
487  if( aMessages )
488  {
489  aMessages->AppendText( _( "Keepout areas ...\n" ) );
490  aMessages->Refresh();
491  }
492 
494  }
495 
496  // find and gather vias, tracks, pads inside text boxes.
497  if( aMessages )
498  {
499  aMessages->AppendText( _( "Test texts...\n" ) );
500  wxSafeYield();
501  }
502 
503  testTexts();
504 
505  // find overlapping courtyard ares.
507  {
508  if( aMessages )
509  {
510  aMessages->AppendText( _( "Courtyard areas...\n" ) );
511  aMessages->Refresh();
512  }
513 
515  }
516 
517  // update the m_drcDialog listboxes
518  updatePointers();
519 
520  if( aMessages )
521  {
522  // no newline on this one because it is last, don't want the window
523  // to unnecessarily scroll.
524  aMessages->AppendText( _( "Finished" ) );
525  }
526 }
527 
528 
530 {
531  testUnconnected();
532 
533  // update the m_drcDialog listboxes
534  updatePointers();
535 }
536 
537 
539 {
540  // update my pointers, m_pcbEditorFrame is the only unchangeable one
542 
543  if( m_drcDialog ) // Use diag list boxes only in DRC dialog
544  {
547 
549  }
550 }
551 
552 
553 bool DRC::doNetClass( const NETCLASSPTR& nc, wxString& msg )
554 {
555  bool ret = true;
556 
558 
559 #define FmtVal( x ) GetChars( StringFromValue( g_UserUnit, x ) )
560 
561 #if 0 // set to 1 when (if...) BOARD_DESIGN_SETTINGS has a m_MinClearance value
562  if( nc->GetClearance() < g.m_MinClearance )
563  {
564  msg.Printf( _( "NETCLASS: \"%s\" has Clearance:%s which is less than global:%s" ),
565  GetChars( nc->GetName() ),
566  FmtVal( nc->GetClearance() ),
567  FmtVal( g.m_TrackClearance )
568  );
569 
571  m_currentMarker = nullptr;
572  ret = false;
573  }
574 #endif
575 
576  if( nc->GetTrackWidth() < g.m_TrackMinWidth )
577  {
578  msg.Printf( _( "NETCLASS: \"%s\" has TrackWidth:%s which is less than global:%s" ),
579  GetChars( nc->GetName() ),
580  FmtVal( nc->GetTrackWidth() ),
582  );
583 
585  m_currentMarker = nullptr;
586  ret = false;
587  }
588 
589  if( nc->GetViaDiameter() < g.m_ViasMinSize )
590  {
591  msg.Printf( _( "NETCLASS: \"%s\" has Via Dia:%s which is less than global:%s" ),
592  GetChars( nc->GetName() ),
593  FmtVal( nc->GetViaDiameter() ),
594  FmtVal( g.m_ViasMinSize )
595  );
596 
598  m_currentMarker = nullptr;
599  ret = false;
600  }
601 
602  if( nc->GetViaDrill() < g.m_ViasMinDrill )
603  {
604  msg.Printf( _( "NETCLASS: \"%s\" has Via Drill:%s which is less than global:%s" ),
605  GetChars( nc->GetName() ),
606  FmtVal( nc->GetViaDrill() ),
608  );
609 
611  m_currentMarker = nullptr;
612  ret = false;
613  }
614 
615  if( nc->GetuViaDiameter() < g.m_MicroViasMinSize )
616  {
617  msg.Printf( _( "NETCLASS: \"%s\" has uVia Dia:%s which is less than global:%s" ),
618  GetChars( nc->GetName() ),
619  FmtVal( nc->GetuViaDiameter() ),
621  );
622 
624  m_currentMarker = nullptr;
625  ret = false;
626  }
627 
628  if( nc->GetuViaDrill() < g.m_MicroViasMinDrill )
629  {
630  msg.Printf( _( "NETCLASS: \"%s\" has uVia Drill:%s which is less than global:%s" ),
631  GetChars( nc->GetName() ),
632  FmtVal( nc->GetuViaDrill() ),
634  );
635 
637  m_currentMarker = nullptr;
638  ret = false;
639  }
640 
641  return ret;
642 }
643 
644 
646 {
647  bool ret = true;
648 
650 
651  wxString msg; // construct this only once here, not in a loop, since somewhat expensive.
652 
653  if( !doNetClass( netclasses.GetDefault(), msg ) )
654  ret = false;
655 
656  for( NETCLASSES::const_iterator i = netclasses.begin(); i != netclasses.end(); ++i )
657  {
658  NETCLASSPTR nc = i->second;
659 
660  if( !doNetClass( nc, msg ) )
661  ret = false;
662  }
663 
664  return ret;
665 }
666 
667 
669 {
670  std::vector<D_PAD*> sortedPads;
671 
672  m_pcb->GetSortedPadListByXthenYCoord( sortedPads );
673 
674  if( sortedPads.size() == 0 )
675  return;
676 
677  // find the max size of the pads (used to stop the test)
678  int max_size = 0;
679 
680  for( unsigned i = 0; i < sortedPads.size(); ++i )
681  {
682  D_PAD* pad = sortedPads[i];
683 
684  // GetBoundingRadius() is the radius of the minimum sized circle fully containing the pad
685  int radius = pad->GetBoundingRadius();
686 
687  if( radius > max_size )
688  max_size = radius;
689  }
690 
691  // Upper limit of pad list (limit not included)
692  D_PAD** listEnd = &sortedPads[0] + sortedPads.size();
693 
694  // Test the pads
695  for( unsigned i = 0; i< sortedPads.size(); ++i )
696  {
697  D_PAD* pad = sortedPads[i];
698 
699  int x_limit = max_size + pad->GetClearance() +
700  pad->GetBoundingRadius() + pad->GetPosition().x;
701 
702  if( !doPadToPadsDrc( pad, &sortedPads[i], listEnd, x_limit ) )
703  {
704  wxASSERT( m_currentMarker );
706  m_currentMarker = nullptr;
707  }
708  }
709 }
710 
711 
712 void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
713 {
714  wxProgressDialog * progressDialog = NULL;
715  const int delta = 500; // This is the number of tests between 2 calls to the
716  // progress bar
717  int count = 0;
718 
719  for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() )
720  count++;
721 
722  int deltamax = count/delta;
723 
724  if( aShowProgressBar && deltamax > 3 )
725  {
726  // Do not use wxPD_APP_MODAL style here: it is not necessary and create issues
727  // on OSX
728  progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString,
729  deltamax, aActiveWindow,
730  wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME );
731  progressDialog->Update( 0, wxEmptyString );
732  }
733 
734  int ii = 0;
735  count = 0;
736 
737  for( TRACK* segm = m_pcb->m_Track; segm; segm = segm->Next() )
738  {
739  if( ii++ > delta )
740  {
741  ii = 0;
742  count++;
743 
744  if( progressDialog )
745  {
746  if( !progressDialog->Update( count, wxEmptyString ) )
747  break; // Aborted by user
748 #ifdef __WXMAC__
749  // Work around a dialog z-order issue on OS X
750  if( count == deltamax )
751  aActiveWindow->Raise();
752 #endif
753  }
754  }
755 
756  if( !doTrackDrc( segm, segm->Next(), true ) )
757  {
758  if( m_currentMarker )
759  {
761  m_currentMarker = nullptr;
762  }
763  }
764  }
765 
766  if( progressDialog )
767  progressDialog->Destroy();
768 }
769 
770 
772 {
773 
774  auto connectivity = m_pcb->GetConnectivity();
775 
776  connectivity->Clear();
777  connectivity->Build( m_pcb ); // just in case. This really needs to be reliable.
778  connectivity->RecalculateRatsnest();
779 
780  std::vector<CN_EDGE> edges;
781  connectivity->GetUnconnectedEdges( edges );
782 
783  for( const auto& edge : edges )
784  {
785  wxString t_src = edge.GetSourceNode()->Parent()->GetSelectMenuText();
786  wxString t_dst = edge.GetTargetNode()->Parent()->GetSelectMenuText();
787  auto src = edge.GetSourcePos();
788  auto dst = edge.GetTargetPos();
789 
790 
791  DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_ITEMS,
792  t_src,
793  t_dst,
794  wxPoint( src.x, src.y ), wxPoint( dst.x, dst.y ) );
795  m_unconnected.push_back( uncItem );
796 
797  }
798 }
799 
800 
802 {
803  // Test copper areas for valid netcodes
804  // if a netcode is < 0 the netname was not found when reading a netlist
805  // if a netcode is == 0 the netname is void, and the zone is not connected.
806  // This is allowed, but i am not sure this is a good idea
807  //
808  // In recent Pcbnew versions, the netcode is always >= 0, but an internal net name
809  // is stored, and initialized from the file or the zone properties editor.
810  // if it differs from the net name from net code, there is a DRC issue
811  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
812  {
813  ZONE_CONTAINER* test_area = m_pcb->GetArea( ii );
814 
815  if( !test_area->IsOnCopperLayer() )
816  continue;
817 
818  int netcode = test_area->GetNetCode();
819 
820  // a netcode < 0 or > 0 and no pad in net is a error or strange
821  // perhaps a "dead" net, which happens when all pads in this net were removed
822  // Remark: a netcode < 0 should not happen (this is more a bug somewhere)
823  int pads_in_net = (test_area->GetNetCode() > 0) ?
824  m_pcb->GetConnectivity()->GetPadCount( test_area->GetNetCode() ) : 1;
825 
826  if( ( netcode < 0 ) || pads_in_net == 0 )
827  {
828  addMarkerToPcb( fillMarker( test_area,
830  m_currentMarker = nullptr;
831  }
832  }
833 
834  // Test copper areas outlines, and create markers when needed
835  TestZoneToZoneOutline( NULL, true );
836 }
837 
838 
840 {
841  // Test keepout areas for vias, tracks and pads inside keepout areas
842  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
843  {
844  ZONE_CONTAINER* area = m_pcb->GetArea( ii );
845 
846  if( !area->GetIsKeepout() )
847  {
848  continue;
849  }
850 
851  for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() )
852  {
853  if( segm->Type() == PCB_TRACE_T )
854  {
855  if( !area->GetDoNotAllowTracks() )
856  continue;
857 
858  // Ignore if the keepout zone is not on the same layer
859  if( !area->IsOnLayer( segm->GetLayer() ) )
860  continue;
861 
862  if( area->Outline()->Distance( SEG( segm->GetStart(), segm->GetEnd() ),
863  segm->GetWidth() ) == 0 )
864  {
865  addMarkerToPcb( fillMarker( segm, NULL,
867  m_currentMarker = nullptr;
868  }
869  }
870  else if( segm->Type() == PCB_VIA_T )
871  {
872  if( ! area->GetDoNotAllowVias() )
873  continue;
874 
875  auto viaLayers = segm->GetLayerSet();
876 
877  if( !area->CommonLayerExists( viaLayers ) )
878  continue;
879 
880  if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 )
881  {
882  addMarkerToPcb( fillMarker( segm, NULL,
884  m_currentMarker = nullptr;
885  }
886  }
887  }
888  // Test pads: TODO
889  }
890 }
891 
892 
894 {
895  std::vector<wxPoint> textShape; // a buffer to store the text shape (set of segments)
896  std::vector<D_PAD*> padList = m_pcb->GetPads();
897 
898  // Test text areas for vias, tracks and pads inside text areas
899  for( auto item : m_pcb->Drawings() )
900  {
901  // Drc test only items on copper layers
902  if( !IsCopperLayer( item->GetLayer() ) )
903  continue;
904 
905  // only texts on copper layers are tested
906  if( item->Type() != PCB_TEXT_T )
907  continue;
908 
909  textShape.clear();
910 
911  // So far the bounding box makes up the text-area
912  TEXTE_PCB* text = (TEXTE_PCB*) item;
913  text->TransformTextShapeToSegmentList( textShape );
914 
915  if( textShape.size() == 0 ) // Should not happen (empty text?)
916  continue;
917 
918  for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
919  {
920  if( !track->IsOnLayer( item->GetLayer() ) )
921  continue;
922 
923  // Test the distance between each segment and the current track/via
924  int min_dist = ( track->GetWidth() + text->GetThickness() ) /2 +
925  track->GetClearance(NULL);
926 
927  if( track->Type() == PCB_TRACE_T )
928  {
929  SEG segref( track->GetStart(), track->GetEnd() );
930 
931  // Error condition: Distance between text segment and track segment is
932  // smaller than the clearance of the segment
933  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
934  {
935  SEG segtest( textShape[jj], textShape[jj+1] );
936  int dist = segref.Distance( segtest );
937 
938  if( dist < min_dist )
939  {
940  addMarkerToPcb( fillMarker( track, text,
942  m_currentMarker ) );
943  m_currentMarker = nullptr;
944  break;
945  }
946  }
947  }
948  else if( track->Type() == PCB_VIA_T )
949  {
950  // Error condition: Distance between text segment and via is
951  // smaller than the clearance of the via
952  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
953  {
954  SEG segtest( textShape[jj], textShape[jj+1] );
955 
956  if( segtest.PointCloserThan( track->GetPosition(), min_dist ) )
957  {
958  addMarkerToPcb( fillMarker( track, text,
960  m_currentMarker = nullptr;
961  break;
962  }
963  }
964  }
965  }
966 
967  // Test pads
968  for( unsigned ii = 0; ii < padList.size(); ii++ )
969  {
970  D_PAD* pad = padList[ii];
971 
972  if( !pad->IsOnLayer( item->GetLayer() ) )
973  continue;
974 
975  wxPoint shape_pos = pad->ShapePos();
976 
977  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
978  {
979  /* In order to make some calculations more easier or faster,
980  * pads and tracks coordinates will be made relative
981  * to the segment origin
982  */
983  wxPoint origin = textShape[jj]; // origin will be the origin of other coordinates
984  m_segmEnd = textShape[jj+1] - origin;
986  m_segmAngle = 0;
987 
988  // for a non horizontal or vertical segment Compute the segment angle
989  // in tenths of degrees and its length
990  if( delta.x || delta.y ) // delta.x == delta.y == 0 for vias
991  {
992  // Compute the segment angle in 0,1 degrees
993  m_segmAngle = ArcTangente( delta.y, delta.x );
994 
995  // Compute the segment length: we build an equivalent rotated segment,
996  // this segment is horizontal, therefore dx = length
997  RotatePoint( &delta, m_segmAngle ); // delta.x = length, delta.y = 0
998  }
999 
1000  m_segmLength = delta.x;
1001  m_padToTestPos = shape_pos - origin;
1002 
1003  if( !checkClearanceSegmToPad( pad, text->GetThickness(),
1004  pad->GetClearance(NULL) ) )
1005  {
1006  addMarkerToPcb( fillMarker( pad, text,
1008  m_currentMarker = nullptr;
1009  break;
1010  }
1011  }
1012  }
1013  }
1014 }
1015 
1016 
1018 {
1019  // Test keepout areas for vias, tracks and pads inside keepout areas
1020  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
1021  {
1022  ZONE_CONTAINER* area = m_pcb->GetArea( ii );
1023 
1024  if( !area->GetIsKeepout() )
1025  continue;
1026 
1027  if( aRefSeg->Type() == PCB_TRACE_T )
1028  {
1029  if( !area->GetDoNotAllowTracks() )
1030  continue;
1031 
1032  if( !area->IsOnLayer( aRefSeg->GetLayer() ) )
1033  continue;
1034 
1035  if( area->Outline()->Distance( SEG( aRefSeg->GetStart(), aRefSeg->GetEnd() ),
1036  aRefSeg->GetWidth() ) == 0 )
1037  {
1038  m_currentMarker = fillMarker( aRefSeg, NULL,
1040  return false;
1041  }
1042  }
1043  else if( aRefSeg->Type() == PCB_VIA_T )
1044  {
1045  if( !area->GetDoNotAllowVias() )
1046  continue;
1047 
1048  auto viaLayers = aRefSeg->GetLayerSet();
1049 
1050  if( !area->CommonLayerExists( viaLayers ) )
1051  continue;
1052 
1053  if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 )
1054  {
1055  m_currentMarker = fillMarker( aRefSeg, NULL,
1057  return false;
1058  }
1059  }
1060  }
1061 
1062  return true;
1063 }
1064 
1065 
1066 bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit )
1067 {
1068  const static LSET all_cu = LSET::AllCuMask();
1069 
1070  LSET layerMask = aRefPad->GetLayerSet() & all_cu;
1071 
1072  /* used to test DRC pad to holes: this dummy pad has the size and shape of the hole
1073  * to test pad to pad hole DRC, using the pad to pad DRC test function.
1074  * Therefore, this dummy pad is a circle or an oval.
1075  * A pad must have a parent because some functions expect a non null parent
1076  * to find the parent board, and some other data
1077  */
1078  MODULE dummymodule( m_pcb ); // Creates a dummy parent
1079  D_PAD dummypad( &dummymodule );
1080 
1081  // Ensure the hole is on all copper layers
1082  dummypad.SetLayerSet( all_cu | dummypad.GetLayerSet() );
1083 
1084  // Use the minimal local clearance value for the dummy pad.
1085  // The clearance of the active pad will be used as minimum distance to a hole
1086  // (a value = 0 means use netclass value)
1087  dummypad.SetLocalClearance( 1 );
1088 
1089  for( D_PAD** pad_list = aStart; pad_list<aEnd; ++pad_list )
1090  {
1091  D_PAD* pad = *pad_list;
1092 
1093  if( pad == aRefPad )
1094  continue;
1095 
1096  // We can stop the test when pad->GetPosition().x > x_limit
1097  // because the list is sorted by X values
1098  if( pad->GetPosition().x > x_limit )
1099  break;
1100 
1101  // No problem if pads which are on copper layers are on different copper layers,
1102  // (pads can be only on a technical layer, to build complex pads)
1103  // but their hole (if any ) can create DRC error because they are on all
1104  // copper layers, so we test them
1105  if( ( pad->GetLayerSet() & layerMask ) == 0 &&
1106  ( pad->GetLayerSet() & all_cu ) != 0 &&
1107  ( aRefPad->GetLayerSet() & all_cu ) != 0 )
1108  {
1109  // if holes are in the same location and have the same size and shape,
1110  // this can be accepted
1111  if( pad->GetPosition() == aRefPad->GetPosition()
1112  && pad->GetDrillSize() == aRefPad->GetDrillSize()
1113  && pad->GetDrillShape() == aRefPad->GetDrillShape() )
1114  {
1115  if( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
1116  continue;
1117 
1118  // for oval holes: must also have the same orientation
1119  if( pad->GetOrientation() == aRefPad->GetOrientation() )
1120  continue;
1121  }
1122 
1123  /* Here, we must test clearance between holes and pads
1124  * dummy pad size and shape is adjusted to pad drill size and shape
1125  */
1126  if( pad->GetDrillSize().x )
1127  {
1128  // pad under testing has a hole, test this hole against pad reference
1129  dummypad.SetPosition( pad->GetPosition() );
1130  dummypad.SetSize( pad->GetDrillSize() );
1131  dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
1133  dummypad.SetOrientation( pad->GetOrientation() );
1134 
1135  if( !checkClearancePadToPad( aRefPad, &dummypad ) )
1136  {
1137  // here we have a drc error on pad!
1138  m_currentMarker = fillMarker( pad, aRefPad,
1140  return false;
1141  }
1142  }
1143 
1144  if( aRefPad->GetDrillSize().x ) // pad reference has a hole
1145  {
1146  dummypad.SetPosition( aRefPad->GetPosition() );
1147  dummypad.SetSize( aRefPad->GetDrillSize() );
1148  dummypad.SetShape( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
1150  dummypad.SetOrientation( aRefPad->GetOrientation() );
1151 
1152  if( !checkClearancePadToPad( pad, &dummypad ) )
1153  {
1154  // here we have a drc error on aRefPad!
1155  m_currentMarker = fillMarker( aRefPad, pad,
1157  return false;
1158  }
1159  }
1160 
1161  continue;
1162  }
1163 
1164  // The pad must be in a net (i.e pt_pad->GetNet() != 0 ),
1165  // But no problem if pads have the same netcode (same net)
1166  if( pad->GetNetCode() && ( aRefPad->GetNetCode() == pad->GetNetCode() ) )
1167  continue;
1168 
1169  // if pads are from the same footprint
1170  if( pad->GetParent() == aRefPad->GetParent() )
1171  {
1172  // and have the same pad number ( equivalent pads )
1173 
1174  // one can argue that this 2nd test is not necessary, that any
1175  // two pads from a single module are acceptable. This 2nd test
1176  // should eventually be a configuration option.
1177  if( pad->PadNameEqual( aRefPad ) )
1178  continue;
1179  }
1180 
1181  // if either pad has no drill and is only on technical layers, not a clearance violation
1182  if( ( ( pad->GetLayerSet() & layerMask ) == 0 && !pad->GetDrillSize().x ) ||
1183  ( ( aRefPad->GetLayerSet() & layerMask ) == 0 && !aRefPad->GetDrillSize().x ) )
1184  {
1185  continue;
1186  }
1187 
1188  if( !checkClearancePadToPad( aRefPad, pad ) )
1189  {
1190  // here we have a drc error!
1192  return false;
1193  }
1194  }
1195 
1196  return true;
1197 }
1198 
1199 
1201 {
1202  // Detects missing (or malformed) footprint courtyard,
1203  // and for footprint with courtyard, courtyards overlap.
1204  wxString msg;
1205  bool success = true;
1206 
1207  // Update courtyard polygons, and test for missing courtyard definition:
1208  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1209  {
1210  bool is_ok = footprint->BuildPolyCourtyard();
1211 
1212  if( !is_ok && m_doFootprintOverlapping )
1213  {
1214  msg.Printf( _( "footprint \"%s\" has malformed courtyard" ),
1215  footprint->GetReference().GetData() );
1216  m_currentMarker = fillMarker( footprint->GetPosition(),
1218  msg, m_currentMarker );
1220  m_currentMarker = nullptr;
1221  success = false;
1222  }
1223 
1224  if( !m_doNoCourtyardDefined )
1225  continue;
1226 
1227  if( footprint->GetPolyCourtyardFront().OutlineCount() == 0 &&
1228  footprint->GetPolyCourtyardBack().OutlineCount() == 0 &&
1229  is_ok )
1230  {
1231  msg.Printf( _( "footprint \"%s\" has no courtyard defined" ),
1232  footprint->GetReference().GetData() );
1233  m_currentMarker = fillMarker( footprint->GetPosition(),
1235  msg, m_currentMarker );
1237  m_currentMarker = nullptr;
1238  success = false;
1239  }
1240  }
1241 
1243  return success;
1244 
1245  // Now test for overlapping on top layer:
1246  SHAPE_POLY_SET courtyard; // temporary storage of the courtyard of current footprint
1247 
1248  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1249  {
1250  if( footprint->GetPolyCourtyardFront().OutlineCount() == 0 )
1251  continue; // No courtyard defined
1252 
1253  for( MODULE* candidate = footprint->Next(); candidate; candidate = candidate->Next() )
1254  {
1255  if( candidate->GetPolyCourtyardFront().OutlineCount() == 0 )
1256  continue; // No courtyard defined
1257 
1258  courtyard.RemoveAllContours();
1259  courtyard.Append( footprint->GetPolyCourtyardFront() );
1260 
1261  // Build the common area between footprint and the candidate:
1262  courtyard.BooleanIntersection( candidate->GetPolyCourtyardFront(),
1264 
1265  // If no overlap, courtyard is empty (no common area).
1266  // Therefore if a common polygon exists, this is a DRC error
1267  if( courtyard.OutlineCount() )
1268  {
1269  //Overlap between footprint and candidate
1270  msg.Printf( _( "footprints \"%s\" and \"%s\" overlap on front (top) layer" ),
1271  footprint->GetReference().GetData(),
1272  candidate->GetReference().GetData() );
1273  VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 );
1274  wxPoint loc( pos.x, pos.y );
1276  m_currentMarker );
1278  m_currentMarker = nullptr;
1279  success = false;
1280  }
1281  }
1282  }
1283 
1284  // Test for overlapping on bottom layer:
1285  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1286  {
1287  if( footprint->GetPolyCourtyardBack().OutlineCount() == 0 )
1288  continue; // No courtyard defined
1289 
1290  for( MODULE* candidate = footprint->Next(); candidate; candidate = candidate->Next() )
1291  {
1292  if( candidate->GetPolyCourtyardBack().OutlineCount() == 0 )
1293  continue; // No courtyard defined
1294 
1295  courtyard.RemoveAllContours();
1296  courtyard.Append( footprint->GetPolyCourtyardBack() );
1297 
1298  // Build the common area between footprint and the candidate:
1299  courtyard.BooleanIntersection( candidate->GetPolyCourtyardBack(),
1301 
1302  // If no overlap, courtyard is empty (no common area).
1303  // Therefore if a common polygon exists, this is a DRC error
1304  if( courtyard.OutlineCount() )
1305  {
1306  //Overlap between footprint and candidate
1307  msg.Printf( _( "footprints \"%s\" and \"%s\" overlap on back (bottom) layer" ),
1308  footprint->GetReference().GetData(),
1309  candidate->GetReference().GetData() );
1310  VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 );
1311  wxPoint loc( pos.x, pos.y );
1313  m_currentMarker );
1315  m_currentMarker = nullptr;
1316  success = false;
1317  }
1318  }
1319  }
1320 
1321  return success;
1322 }
bool m_refillZones
Definition: drc.h:176
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
bool doNetClass(const std::shared_ptr< NETCLASS > &aNetClass, wxString &msg)
Definition: drc.cpp:553
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:673
bool m_doNoCourtyardDefined
Definition: drc.h:175
KICAD_T Type() const
Function Type()
Definition: base_struct.h:209
bool m_doCreateRptFile
Definition: drc.h:173
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
#define DRCE_TRACK_INSIDE_TEXT
Track in inside a text area.
Definition: drc.h:85
#define OK_DRC
Definition: drc.h:35
void DestroyDRCDialog(int aReason)
Deletes this ui dialog box and zeros out its pointer to remember the state of the dialog&#39;s existence...
Definition: drc.cpp:117
bool PadNameEqual(const D_PAD *other) const
Definition: class_pad.h:207
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc.h:219
void UpdateDisplayedCounts()
Definition: dialog_drc.cpp:760
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
TEXTE_PCB class definition.
bool CommonLayerExists(const LSET aLayerSet) const
Function CommonLayerExist Test if this zone shares a common layer with the given layer set...
Definition: class_zone.cpp:194
Class DRC_ITEM is a holder for a DRC (in Pcbnew) or ERC (in Eeschema) error item. ...
Definition: drc_item.h:45
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Returns an iterator object, for all outlines in the set (with holes)
#define DRCE_PAD_NEAR_PAD1
pad too close to pad
Definition: drc.h:62
MARKER_PCB * fillMarker(const TRACK *aTrack, BOARD_ITEM *aItem, int aErrorCode, MARKER_PCB *fillMe)
Creates a marker and fills it in with information but does not add it to the BOARD.
Implementation of conversion functions that require both schematic and board internal units...
int TestZoneToZoneOutline(ZONE_CONTAINER *aZone, bool aCreateMarkers)
Tests whether distance between zones complies with the DRC rules.
Definition: drc.cpp:213
int m_ycliplo
Definition: drc.h:213
#define DRCE_NETCLASS_TRACKWIDTH
netclass has TrackWidth < board.m_designSettings->m_TrackMinWidth
Definition: drc.h:75
#define DRCE_HOLE_NEAR_PAD
hole too close to pad
Definition: drc.h:68
COMMIT & Add(EDA_ITEM *aItem)
Adds a new item to the model
Definition: commit.h:78
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void SetList(DRC_ITEM_LIST *aList)
Function SetList sets the DRC_ITEM_LIST for this listbox.
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: class_zone.cpp:265
void testKeepoutAreas()
Definition: drc.cpp:839
void GetRptSettings(bool *aEnable, wxString &aFileName)
Definition: dialog_drc.cpp:191
void Check_All_Zones(wxWindow *aActiveWindow)
Function Check_All_Zones Checks for out-of-date fills and fills them if requested by the user...
MODULE * Next() const
Definition: class_module.h:121
void GetSortedPadListByXthenYCoord(std::vector< D_PAD * > &aVector, int aNetCode=-1)
Function GetSortedPadListByXthenYCoord first empties then fills the vector with all pads and sorts th...
MODULE * GetParent() const
Definition: class_pad.h:162
static TOOL_ACTION cancelInteractive
Definition: actions.h:45
int m_ycliphi
Definition: drc.h:215
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:175
static const int dist[10][10]
Definition: dist.cpp:57
bool BuildSmoothedPoly(SHAPE_POLY_SET &aSmoothedPoly) const
Function GetSmoothedPoly returns a pointer to the corner-smoothed version of m_Poly if it exists...
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:236
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, bool aIgnoreHoles=false) const
Returns true if a given subpolygon contains the point aP.
#define DRCE_VIA_INSIDE_KEEPOUT
Via in inside a keepout area.
Definition: drc.h:81
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
int m_segmLength
Definition: drc.h:207
#define COPPERAREA_INSIDE_COPPERAREA
copper area outlines intersect
Definition: drc.h:65
BOARD * GetBoard() const
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:219
Classes to handle copper zones.
void ListUnconnectedPads()
Gather a list of all the unconnected pads and shows them in the dialog, and optionally prints a repor...
Definition: drc.cpp:529
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:388
iterator end()
Definition: netclass.h:256
#define DRCE_NETCLASS_CLEARANCE
netclass has Clearance < board.m_designSettings->m_TrackClearance
Definition: drc.h:76
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
int GetClearanceBetweenSegments(int x1i, int y1i, int x1f, int y1f, int w1, int x2i, int y2i, int x2f, int y2f, int w2, int max_cl, int *x, int *y)
int OutlineCount() const
Returns the number of outlines in the set
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
wxPoint m_padToTestPos
Definition: drc.h:198
#define DRCE_UNCONNECTED_ITEMS
items are unconnected
Definition: drc.h:45
DRCLISTBOX * m_UnconnectedListBox
NETCLASS_MAP::const_iterator const_iterator
Definition: netclass.h:258
static const int delta[8][2]
Definition: solve.cpp:112
void DeactivateTool()
Function DeactivateTool() Deactivates the currently active tool.
const wxPoint & GetEnd() const
Definition: class_track.h:119
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_zone.cpp:780
#define DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE
copper area has a net but no pads in nets, which is suspicious
Definition: drc.h:67
#define DRCE_MALFORMED_COURTYARD_IN_FOOTPRINT
footprint has a courtyard but malformed
Definition: drc.h:89
#define DRCE_MISSING_COURTYARD_IN_FOOTPRINT
footprint has no courtyard defined
Definition: drc.h:88
Functions relatives to tracks, vias and segments used to fill zones.
int DrcOnCreatingTrack(TRACK *aRefSeg, TRACK *aList)
tests the current segment and returns the result and displays the error in the status panel only if o...
Definition: drc.cpp:175
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void testTexts()
Definition: drc.cpp:893
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:152
bool doTrackKeepoutDrc(TRACK *aRefSeg)
Test the current segment or via.
Definition: drc.cpp:1017
BOARD * m_pcb
Definition: drc.h:218
bool m_doFootprintOverlapping
Definition: drc.h:174
VECTOR2I & Vertex(int aIndex, int aOutline, int aHole)
Returns the index-th vertex in a given hole outline within a given outline
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:602
#define COPPERAREA_CLOSE_TO_COPPERAREA
copper area outlines are too close
Definition: drc.h:66
Class TOOL_MANAGER.
Definition: tool_manager.h:49
#define DRCE_NETCLASS_uVIADRILLSIZE
netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill
Definition: drc.h:80
#define DRCE_NETCLASS_VIASIZE
netclass has ViaSize < board.m_designSettings->m_ViasMinSize
Definition: drc.h:77
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:98
bool m_doKeepoutTest
Definition: drc.h:172
Class LSET is a set of PCB_LAYER_IDs.
bool m_doZonesTest
Definition: drc.h:171
iterator begin()
Definition: netclass.h:255
Class NETCLASSES is a container for NETCLASS instances.
Definition: netclass.h:231
const wxPoint GetPosition() const override
Definition: class_track.h:113
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
void testZones()
Definition: drc.cpp:801
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:831
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:599
ITERATOR IterateWithHoles(int aOutline)
Function IterateWithHoles.
Class SHAPE_POLY_SET.
DRCLISTBOX * m_ClearanceListBox
bool m_abortDRC
Definition: drc.h:183
bool m_drcInProgress
Definition: drc.h:184
Class DRC_LIST_MARKERS is an implementation of the interface named DRC_ITEM_LIST which uses a BOARD i...
const wxPoint & GetStart() const
Definition: class_track.h:122
int m_TrackMinWidth
track min value for width ((min copper size value
DRC(PCB_EDIT_FRAME *aPcbWindow)
Definition: drc.cpp:133
int m_ViasMinSize
vias (not micro vias) min diameter
void updatePointers()
Update needed pointers from the one pointer which is known not to change.
Definition: drc.cpp:538
int DrcOnCreatingZone(ZONE_CONTAINER *aArea, int aCornerIndex)
tests the outline segment starting at CornerIndex and returns the result and displays the error in th...
Definition: drc.cpp:374
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:402
int m_ViasMinDrill
vias (not micro vias) min drill diameter
virtual LSET GetLayerSet() const
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:535
void SetSize(const wxSize &aSize)
Definition: class_pad.h:268
#define DRCE_OVERLAPPING_FOOTPRINTS
footprint courtyards overlap
Definition: drc.h:87
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1015
bool m_reportAllTrackErrors
Definition: drc.h:177
#define DRCE_NETCLASS_VIADRILLSIZE
netclass has ViaDrillSize < board.m_designSettings->m_ViasMinDrill
Definition: drc.h:78
#define DRCE_VIA_INSIDE_TEXT
Via in inside a text area.
Definition: drc.h:84
bool doPadToPadsDrc(D_PAD *aRefPad, D_PAD **aStart, D_PAD **aEnd, int x_limit)
Test the clearance between aRefPad and other pads.
Definition: drc.cpp:1066
int m_xcliphi
Definition: drc.h:214
int m_MicroViasMinSize
micro vias (not vias) min diameter
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:217
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset intersection For aFastMode meaning, see function booleanOp ...
#define DRCE_PAD_INSIDE_TEXT
Pad in inside a text area.
Definition: drc.h:86
bool m_doPad2PadTest
Definition: drc.h:169
void testPad2Pad()
Definition: drc.cpp:668
#define BAD_DRC
Definition: drc.h:36
bool Show(bool show) override
bool doEdgeZoneDrc(ZONE_CONTAINER *aArea, int aCornerIndex)
Test a segment in ZONE_CONTAINER * aArea: Test Edge inside other areas Test Edge too close other area...
Pad object description.
void SetLocalClearance(int aClearance)
Definition: class_pad.h:414
#define FmtVal(x)
friend class DIALOG_DRC_CONTROL
Definition: drc.h:164
bool checkClearancePadToPad(D_PAD *aRefPad, D_PAD *aPad)
int GetNetCode() const
Function GetNetCode.
MARKER_PCB * m_currentMarker
Definition: drc.h:181
Definition: seg.h:36
bool doFootprintOverlappingDrc()
Test for footprint courtyard overlaps.
Definition: drc.cpp:1200
bool checkClearanceSegmToPad(const D_PAD *aPad, int aSegmentWidth, int aMinDist)
Check the distance from a pad to segment.
const std::vector< D_PAD * > GetPads()
Function GetPads returns a reference to a list of all the pads.
wxPoint m_segmEnd
Definition: drc.h:199
TOOL_MANAGER * GetToolManager() const
Function GetToolManager returns the tool manager instance, if any.
Definition: draw_frame.h:910
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:401
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.cpp:181
bool GetDoNotAllowTracks() const
Definition: class_zone.h:605
bool testNetClasses()
Go through each NETCLASS and verifies that its clearance, via size, track width, and track clearance ...
Definition: drc.cpp:645
void testTracks(wxWindow *aActiveWindow, bool aShowProgressBar)
Perform the DRC on all tracks.
Definition: drc.cpp:712
TRACK * Next() const
Definition: class_track.h:99
void ShowDRCDialog(wxWindow *aParent=NULL)
Open a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and create...
Definition: drc.cpp:59
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:986
wxString m_rptFilename
Definition: drc.h:179
bool GetDoNotAllowVias() const
Definition: class_zone.h:604
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
DLIST< MODULE > m_Modules
Definition: class_board.h:247
int GetWidth() const
Definition: class_track.h:116
int Distance(VECTOR2I aPoint)
Function DistanceToPolygon computes the minimum distance between aPoint and all the polygons in the s...
void TransformTextShapeToSegmentList(std::vector< wxPoint > &aCornerBuffer) const
Convert the text shape to a list of segment each segment is stored as 2 wxPoints: the starting point ...
Definition: eda_text.cpp:479
NETCLASSPTR GetDefault() const
Function GetDefault.
Definition: netclass.h:275
size_t i
Definition: json11.cpp:597
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:382
VECTOR2I A
Definition: seg.h:46
#define DRCE_TRACK_INSIDE_KEEPOUT
Track in inside a keepout area.
Definition: drc.h:82
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_pad.cpp:546
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
void SetShape(PAD_SHAPE_T aShape)
Definition: class_pad.h:217
wxPoint ShapePos() const
Definition: class_pad.cpp:500
void SetOrientation(double aAngle)
Function SetOrientation sets the rotation angle of the pad.
Definition: class_pad.cpp:401
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
int Fill_All_Zones(wxWindow *aActiveWindow)
Function Fill_All_Zones Fill all zones on the board The old fillings are removed. ...
bool doTrackDrc(TRACK *aRefSeg, TRACK *aStart, bool doPads=true)
Test the current segment.
DLIST< TRACK > m_Track
Definition: class_board.h:248
Class DRC_LIST_UNCONNECTED is an implementation of the interface named DRC_ITEM_LIST which uses a vec...
bool PointCloserThan(const VECTOR2I &aP, int aDist) const
Definition: seg.cpp:34
Module description (excepted pads)
int m_MicroViasMinDrill
micro vias (not vias) min drill diameter
unsigned GetPriority() const
Function GetPriority.
Definition: class_zone.h:101
DRC_LIST m_unconnected
list of unconnected pads, as DRC_ITEMs
Definition: drc.h:221
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: class_pad.h:650
const wxPoint GetPosition() const override
Definition: class_pad.h:220
~DRC()
Definition: drc.cpp:167
void testUnconnected()
Definition: drc.cpp:771
void RunTests(wxTextCtrl *aMessages=NULL)
Run all the tests specified with a previous call to SetSettings()
Definition: drc.cpp:401
bool m_drcInLegacyRoutingMode
in legacy canvas, when creating a track, the drc test must only display the error message...
Definition: drc.h:192
int m_xcliplo
Definition: drc.h:212
#define DRCE_NETCLASS_uVIASIZE
netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize
Definition: drc.h:79
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:293
bool m_doUnconnectedTest
Definition: drc.h:170
double m_segmAngle
Definition: drc.h:206
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:254
void SetRptSettings(bool aEnable, const wxString &aFileName)
Enable/disable the report file creation.
Definition: dialog_drc.cpp:182
NETCLASSES m_NetClasses
List of current netclasses. There is always the default netclass.
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline) ...
VECTOR2I B
Definition: seg.h:47