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 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 <wxPcbStruct.h>
32 #include <trigo.h>
33 #include <base_units.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 
45 #include <connectivity.h>
46 #include <connectivity_algo.h>
47 
48 #include <tool/tool_manager.h>
49 #include <tools/pcb_actions.h>
50 
51 #include <pcbnew.h>
52 #include <drc_stuff.h>
53 
54 #include <dialog_drc.h>
55 #include <wx/progdlg.h>
56 #include <board_commit.h>
57 
58 void DRC::ShowDRCDialog( wxWindow* aParent )
59 {
60  bool show_dlg_modal = true;
61 
62  // the dialog needs a parent frame. if it is not specified, this is
63  // the PCB editor frame specified in DRC class.
64  if( aParent == NULL )
65  {
66  // if any parent is specified, the dialog is modal.
67  // if this is the default PCB editor frame, it is not modal
68  show_dlg_modal = false;
69  aParent = m_pcbEditorFrame;
70  }
71 
72  if( !m_drcDialog )
73  {
75  m_drcDialog = new DIALOG_DRC_CONTROL( this, m_pcbEditorFrame, aParent );
77 
79 
80  if( show_dlg_modal )
81  m_drcDialog->ShowModal();
82  else
83  m_drcDialog->Show( true );
84  }
85  else // The dialog is just not visible (because the user has double clicked on an error item)
86  {
88  m_drcDialog->Show( true );
89  }
90 }
91 
93 {
94  BOARD_COMMIT commit ( m_pcbEditorFrame );
95  commit.Add( aMarker );
96  commit.Push( wxEmptyString, false );
97 }
98 
99 void DRC::DestroyDRCDialog( int aReason )
100 {
101  if( m_drcDialog )
102  {
103  if( aReason == wxID_OK )
104  {
105  // if user clicked OK, save his choices in this DRC object.
107  }
108 
109  m_drcDialog->Destroy();
110  m_drcDialog = NULL;
111  }
112 }
113 
114 
115 DRC::DRC( PCB_EDIT_FRAME* aPcbWindow )
116 {
117  m_pcbEditorFrame = aPcbWindow;
118  m_pcb = aPcbWindow->GetBoard();
119  m_drcDialog = NULL;
120 
121  // establish initial values for everything:
122  m_doPad2PadTest = true; // enable pad to pad clearance tests
123  m_doUnconnectedTest = true; // enable unconnected tests
124  m_doZonesTest = true; // enable zone to items clearance tests
125  m_doKeepoutTest = true; // enable keepout areas to items clearance tests
126  m_doFootprintOverlapping = true; // enable courtyards areas overlap tests
127  m_doNoCourtyardDefined = true; // enable missing courtyard in footprint warning
128  m_abortDRC = false;
129  m_drcInProgress = false;
130 
131  m_doCreateRptFile = false;
132 
133  // m_rptFilename set to empty by its constructor
134 
135  m_currentMarker = NULL;
136 
137  m_segmAngle = 0;
138  m_segmLength = 0;
139 
140  m_xcliplo = 0;
141  m_ycliplo = 0;
142  m_xcliphi = 0;
143  m_ycliphi = 0;
144 }
145 
146 
148 {
149  // maybe someday look at pointainer.h <- google for "pointainer.h"
150  for( unsigned i = 0; i<m_unconnected.size(); ++i )
151  delete m_unconnected[i];
152 }
153 
154 
155 int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
156 {
157  updatePointers();
158 
159  if( !doTrackDrc( aRefSegm, aList, true ) )
160  {
161  wxASSERT( m_currentMarker );
162 
164  return BAD_DRC;
165  }
166 
167  if( !doTrackKeepoutDrc( aRefSegm ) )
168  {
169  wxASSERT( m_currentMarker );
170 
172  return BAD_DRC;
173  }
174 
175  return OK_DRC;
176 }
177 
178 
179 int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex )
180 {
181  updatePointers();
182 
183  if( !doEdgeZoneDrc( aArea, aCornerIndex ) )
184  {
185  wxASSERT( m_currentMarker );
187  return BAD_DRC;
188  }
189 
190  return OK_DRC;
191 }
192 
193 
194 void DRC::RunTests( wxTextCtrl* aMessages )
195 {
196  // be sure m_pcb is the current board, not a old one
197  // ( the board can be reloaded )
199 
200  // someone should have cleared the two lists before calling this.
201 
202  if( !testNetClasses() )
203  {
204  // testing the netclasses is a special case because if the netclasses
205  // do not pass the BOARD_DESIGN_SETTINGS checks, then every member of a net
206  // class (a NET) will cause its items such as tracks, vias, and pads
207  // to also fail. So quit after *all* netclass errors have been reported.
208  if( aMessages )
209  aMessages->AppendText( _( "Aborting\n" ) );
210 
211  // update the m_drcDialog listboxes
212  updatePointers();
213 
214  return;
215  }
216 
217  // test pad to pad clearances, nothing to do with tracks, vias or zones.
218  if( m_doPad2PadTest )
219  {
220  if( aMessages )
221  {
222  aMessages->AppendText( _( "Pad clearances...\n" ) );
223  wxSafeYield();
224  }
225 
226  testPad2Pad();
227  }
228 
229  // test track and via clearances to other tracks, pads, and vias
230  if( aMessages )
231  {
232  aMessages->AppendText( _( "Track clearances...\n" ) );
233  wxSafeYield();
234  }
235 
236  testTracks( aMessages ? aMessages->GetParent() : m_pcbEditorFrame, true );
237 
238  // Before testing segments and unconnected, refill all zones:
239  // this is a good caution, because filled areas can be outdated.
240  if( aMessages )
241  {
242  aMessages->AppendText( _( "Fill zones...\n" ) );
243  wxSafeYield();
244  }
245 
246  m_pcbEditorFrame->Fill_All_Zones( aMessages ? aMessages->GetParent() : m_pcbEditorFrame,
247  false );
248 
249  // test zone clearances to other zones
250  if( aMessages )
251  {
252  aMessages->AppendText( _( "Test zones...\n" ) );
253  wxSafeYield();
254  }
255 
256  testZones();
257 
258  // find and gather unconnected pads.
259  if( m_doUnconnectedTest )
260  {
261  if( aMessages )
262  {
263  aMessages->AppendText( _( "Unconnected pads...\n" ) );
264  aMessages->Refresh();
265  }
266 
267  testUnconnected();
268  }
269 
270  // find and gather vias, tracks, pads inside keepout areas.
271  if( m_doKeepoutTest )
272  {
273  if( aMessages )
274  {
275  aMessages->AppendText( _( "Keepout areas ...\n" ) );
276  aMessages->Refresh();
277  }
278 
280  }
281 
282  // find and gather vias, tracks, pads inside text boxes.
283  if( aMessages )
284  {
285  aMessages->AppendText( _( "Test texts...\n" ) );
286  wxSafeYield();
287  }
288 
289  testTexts();
290 
291  // find overlaping courtyard ares.
293  {
294  if( aMessages )
295  {
296  aMessages->AppendText( _( "Courtyard areas...\n" ) );
297  aMessages->Refresh();
298  }
299 
301  }
302 
303  // update the m_drcDialog listboxes
304  updatePointers();
305 
306  if( aMessages )
307  {
308  // no newline on this one because it is last, don't want the window
309  // to unnecessarily scroll.
310  aMessages->AppendText( _( "Finished" ) );
311  }
312 }
313 
314 
316 {
317  testUnconnected();
318 
319  // update the m_drcDialog listboxes
320  updatePointers();
321 }
322 
323 
325 {
326  // update my pointers, m_pcbEditorFrame is the only unchangeable one
328 
329  if( m_drcDialog ) // Use diag list boxes only in DRC dialog
330  {
333 
335  }
336 }
337 
338 
339 bool DRC::doNetClass( NETCLASSPTR nc, wxString& msg )
340 {
341  bool ret = true;
342 
344 
345 #define FmtVal( x ) GetChars( StringFromValue( g_UserUnit, x ) )
346 
347 #if 0 // set to 1 when (if...) BOARD_DESIGN_SETTINGS has a m_MinClearance value
348  if( nc->GetClearance() < g.m_MinClearance )
349  {
350  msg.Printf( _( "NETCLASS: '%s' has Clearance:%s which is less than global:%s" ),
351  GetChars( nc->GetName() ),
352  FmtVal( nc->GetClearance() ),
353  FmtVal( g.m_TrackClearance )
354  );
355 
357  m_currentMarker = nullptr;
358  ret = false;
359  }
360 #endif
361 
362  if( nc->GetTrackWidth() < g.m_TrackMinWidth )
363  {
364  msg.Printf( _( "NETCLASS: '%s' has TrackWidth:%s which is less than global:%s" ),
365  GetChars( nc->GetName() ),
366  FmtVal( nc->GetTrackWidth() ),
368  );
369 
371  m_currentMarker = nullptr;
372  ret = false;
373  }
374 
375  if( nc->GetViaDiameter() < g.m_ViasMinSize )
376  {
377  msg.Printf( _( "NETCLASS: '%s' has Via Dia:%s which is less than global:%s" ),
378  GetChars( nc->GetName() ),
379  FmtVal( nc->GetViaDiameter() ),
380  FmtVal( g.m_ViasMinSize )
381  );
382 
384  m_currentMarker = nullptr;
385  ret = false;
386  }
387 
388  if( nc->GetViaDrill() < g.m_ViasMinDrill )
389  {
390  msg.Printf( _( "NETCLASS: '%s' has Via Drill:%s which is less than global:%s" ),
391  GetChars( nc->GetName() ),
392  FmtVal( nc->GetViaDrill() ),
394  );
395 
397  m_currentMarker = nullptr;
398  ret = false;
399  }
400 
401  if( nc->GetuViaDiameter() < g.m_MicroViasMinSize )
402  {
403  msg.Printf( _( "NETCLASS: '%s' has uVia Dia:%s which is less than global:%s" ),
404  GetChars( nc->GetName() ),
405  FmtVal( nc->GetuViaDiameter() ),
407  );
408 
410  m_currentMarker = nullptr;
411  ret = false;
412  }
413 
414  if( nc->GetuViaDrill() < g.m_MicroViasMinDrill )
415  {
416  msg.Printf( _( "NETCLASS: '%s' has uVia Drill:%s which is less than global:%s" ),
417  GetChars( nc->GetName() ),
418  FmtVal( nc->GetuViaDrill() ),
420  );
421 
423  m_currentMarker = nullptr;
424  ret = false;
425  }
426 
427  return ret;
428 }
429 
430 
432 {
433  bool ret = true;
434 
436 
437  wxString msg; // construct this only once here, not in a loop, since somewhat expensive.
438 
439  if( !doNetClass( netclasses.GetDefault(), msg ) )
440  ret = false;
441 
442  for( NETCLASSES::const_iterator i = netclasses.begin(); i != netclasses.end(); ++i )
443  {
444  NETCLASSPTR nc = i->second;
445 
446  if( !doNetClass( nc, msg ) )
447  ret = false;
448  }
449 
450  return ret;
451 }
452 
453 
455 {
456  std::vector<D_PAD*> sortedPads;
457 
458  m_pcb->GetSortedPadListByXthenYCoord( sortedPads );
459 
460  // find the max size of the pads (used to stop the test)
461  int max_size = 0;
462 
463  for( unsigned i = 0; i < sortedPads.size(); ++i )
464  {
465  D_PAD* pad = sortedPads[i];
466 
467  // GetBoundingRadius() is the radius of the minimum sized circle fully containing the pad
468  int radius = pad->GetBoundingRadius();
469  if( radius > max_size )
470  max_size = radius;
471  }
472 
473  // Test the pads
474  D_PAD** listEnd = &sortedPads[ sortedPads.size() ];
475 
476  for( unsigned i = 0; i< sortedPads.size(); ++i )
477  {
478  D_PAD* pad = sortedPads[i];
479 
480  int x_limit = max_size + pad->GetClearance() +
481  pad->GetBoundingRadius() + pad->GetPosition().x;
482 
483  if( !doPadToPadsDrc( pad, &sortedPads[i], listEnd, x_limit ) )
484  {
485  wxASSERT( m_currentMarker );
487  m_currentMarker = nullptr;
488  }
489  }
490 }
491 
492 
493 void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
494 {
495  wxProgressDialog * progressDialog = NULL;
496  const int delta = 500; // This is the number of tests between 2 calls to the
497  // progress bar
498  int count = 0;
499  for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() )
500  count++;
501 
502  int deltamax = count/delta;
503 
504  if( aShowProgressBar && deltamax > 3 )
505  {
506  progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString,
507  deltamax, aActiveWindow,
508  wxPD_AUTO_HIDE | wxPD_CAN_ABORT |
509  wxPD_APP_MODAL | wxPD_ELAPSED_TIME );
510  progressDialog->Update( 0, wxEmptyString );
511  }
512 
513  int ii = 0;
514  count = 0;
515 
516  for( TRACK* segm = m_pcb->m_Track; segm; segm = segm->Next() )
517  {
518  if ( ii++ > delta )
519  {
520  ii = 0;
521  count++;
522 
523  if( progressDialog )
524  {
525  if( !progressDialog->Update( count, wxEmptyString ) )
526  break; // Aborted by user
527 #ifdef __WXMAC__
528  // Work around a dialog z-order issue on OS X
529  if( count == deltamax )
530  aActiveWindow->Raise();
531 #endif
532  }
533  }
534 
535  if( !doTrackDrc( segm, segm->Next(), true ) )
536  {
537  wxASSERT( m_currentMarker );
539  m_currentMarker = nullptr;
540  }
541  }
542 
543  if( progressDialog )
544  progressDialog->Destroy();
545 }
546 
547 
549 {
550 
551  auto connectivity = m_pcb->GetConnectivity();
552 
553  connectivity->Clear();
554  connectivity->Build(m_pcb); // just in case. This really needs to be reliable.
555  connectivity->RecalculateRatsnest();
556 
557  std::vector<CN_EDGE> edges;
558  connectivity->GetUnconnectedEdges( edges );
559 
560  for( const auto& edge : edges )
561  {
562  wxString t_src = edge.GetSourceNode()->Parent()->GetSelectMenuText();
563  wxString t_dst = edge.GetTargetNode()->Parent()->GetSelectMenuText();
564  auto src = edge.GetSourcePos();
565  auto dst = edge.GetTargetPos();
566 
567 
568  DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_ITEMS,
569  t_src,
570  t_dst,
571  wxPoint( src.x, src.y ), wxPoint( dst.x, dst.y ) );
572  m_unconnected.push_back( uncItem );
573 
574  }
575 }
576 
577 
579 {
580  // Test copper areas for valid netcodes
581  // if a netcode is < 0 the netname was not found when reading a netlist
582  // if a netcode is == 0 the netname is void, and the zone is not connected.
583  // This is allowed, but i am not sure this is a good idea
584  //
585  // In recent Pcbnew versions, the netcode is always >= 0, but an internal net name
586  // is stored, and initalized from the file or the zone properpies editor.
587  // if it differs from the net name from net code, there is a DRC issue
588  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
589  {
590  ZONE_CONTAINER* test_area = m_pcb->GetArea( ii );
591 
592  if( !test_area->IsOnCopperLayer() )
593  continue;
594 
595  int netcode = test_area->GetNetCode();
596 
597  // a netcode < 0 or > 0 and no pad in net is a error or strange
598  // perhaps a "dead" net, which happens when all pads in this net were removed
599  // Remark: a netcode < 0 should not happen (this is more a bug somewhere)
600  int pads_in_net = (test_area->GetNetCode() > 0) ?
601  m_pcb->GetConnectivity()->GetPadCount( test_area->GetNetCode() ) : 1;
602 
603  if( ( netcode < 0 ) || pads_in_net == 0 )
604  {
605  addMarkerToPcb( fillMarker( test_area,
607  m_currentMarker = nullptr;
608  }
609  }
610 
611  // Test copper areas outlines, and create markers when needed
613 }
614 
615 
617 {
618  // Test keepout areas for vias, tracks and pads inside keepout areas
619  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
620  {
621  ZONE_CONTAINER* area = m_pcb->GetArea( ii );
622 
623  if( !area->GetIsKeepout() )
624  {
625  continue;
626  }
627 
628  for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() )
629  {
630  if( segm->Type() == PCB_TRACE_T )
631  {
632  if( ! area->GetDoNotAllowTracks() )
633  continue;
634 
635  // Ignore if the keepout zone is not on the same layer
636  if( !area->IsOnLayer( segm->GetLayer() ) )
637  continue;
638 
639  if( area->Outline()->Distance( SEG( segm->GetStart(), segm->GetEnd() ),
640  segm->GetWidth() ) == 0 )
641  {
642  addMarkerToPcb( fillMarker( segm, NULL,
644  m_currentMarker = nullptr;
645  }
646  }
647  else if( segm->Type() == PCB_VIA_T )
648  {
649  if( ! area->GetDoNotAllowVias() )
650  continue;
651 
652  auto viaLayers = segm->GetLayerSet();
653 
654  if( !area->CommonLayerExists( viaLayers ) )
655  continue;
656 
657  if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 )
658  {
659  addMarkerToPcb( fillMarker( segm, NULL,
661  m_currentMarker = nullptr;
662  }
663  }
664  }
665  // Test pads: TODO
666  }
667 }
668 
669 
671 {
672  std::vector<wxPoint> textShape; // a buffer to store the text shape (set of segments)
673  std::vector<D_PAD*> padList = m_pcb->GetPads();
674 
675  // Test text areas for vias, tracks and pads inside text areas
676  for( auto item : m_pcb->Drawings() )
677  {
678  // Drc test only items on copper layers
679  if( ! IsCopperLayer( item->GetLayer() ) )
680  continue;
681 
682  // only texts on copper layers are tested
683  if( item->Type() != PCB_TEXT_T )
684  continue;
685 
686  textShape.clear();
687 
688  // So far the bounding box makes up the text-area
689  TEXTE_PCB* text = (TEXTE_PCB*) item;
690  text->TransformTextShapeToSegmentList( textShape );
691 
692  if( textShape.size() == 0 ) // Should not happen (empty text?)
693  continue;
694 
695  for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
696  {
697  if( ! track->IsOnLayer( item->GetLayer() ) )
698  continue;
699 
700  // Test the distance between each segment and the current track/via
701  int min_dist = ( track->GetWidth() + text->GetThickness() ) /2 +
702  track->GetClearance(NULL);
703 
704  if( track->Type() == PCB_TRACE_T )
705  {
706  SEG segref( track->GetStart(), track->GetEnd() );
707 
708  // Error condition: Distance between text segment and track segment is
709  // smaller than the clearance of the segment
710  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
711  {
712  SEG segtest( textShape[jj], textShape[jj+1] );
713  int dist = segref.Distance( segtest );
714 
715  if( dist < min_dist )
716  {
717  addMarkerToPcb( fillMarker( track, text,
719  m_currentMarker ) );
720  m_currentMarker = nullptr;
721  break;
722  }
723  }
724  }
725  else if( track->Type() == PCB_VIA_T )
726  {
727  // Error condition: Distance between text segment and via is
728  // smaller than the clearance of the via
729  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
730  {
731  SEG segtest( textShape[jj], textShape[jj+1] );
732 
733  if( segtest.PointCloserThan( track->GetPosition(), min_dist ) )
734  {
735  addMarkerToPcb( fillMarker( track, text,
737  m_currentMarker = nullptr;
738  break;
739  }
740  }
741  }
742  }
743 
744  // Test pads
745  for( unsigned ii = 0; ii < padList.size(); ii++ )
746  {
747  D_PAD* pad = padList[ii];
748 
749  if( ! pad->IsOnLayer( item->GetLayer() ) )
750  continue;
751 
752  wxPoint shape_pos = pad->ShapePos();
753 
754  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
755  {
756  /* In order to make some calculations more easier or faster,
757  * pads and tracks coordinates will be made relative
758  * to the segment origin
759  */
760  wxPoint origin = textShape[jj]; // origin will be the origin of other coordinates
761  m_segmEnd = textShape[jj+1] - origin;
763  m_segmAngle = 0;
764 
765  // for a non horizontal or vertical segment Compute the segment angle
766  // in tenths of degrees and its length
767  if( delta.x || delta.y ) // delta.x == delta.y == 0 for vias
768  {
769  // Compute the segment angle in 0,1 degrees
770  m_segmAngle = ArcTangente( delta.y, delta.x );
771 
772  // Compute the segment length: we build an equivalent rotated segment,
773  // this segment is horizontal, therefore dx = length
774  RotatePoint( &delta, m_segmAngle ); // delta.x = length, delta.y = 0
775  }
776 
777  m_segmLength = delta.x;
778  m_padToTestPos = shape_pos - origin;
779 
780  if( !checkClearanceSegmToPad( pad, text->GetThickness(),
781  pad->GetClearance(NULL) ) )
782  {
783  addMarkerToPcb( fillMarker( pad, text,
785  m_currentMarker = nullptr;
786  break;
787  }
788  }
789  }
790  }
791 }
792 
793 
795 {
796  // Test keepout areas for vias, tracks and pads inside keepout areas
797  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
798  {
799  ZONE_CONTAINER* area = m_pcb->GetArea( ii );
800 
801  if( !area->GetIsKeepout() )
802  continue;
803 
804  if( aRefSeg->Type() == PCB_TRACE_T )
805  {
806  if( ! area->GetDoNotAllowTracks() )
807  continue;
808 
809  if( !area->IsOnLayer( aRefSeg->GetLayer() ) )
810  continue;
811 
812  if( area->Outline()->Distance( SEG( aRefSeg->GetStart(), aRefSeg->GetEnd() ),
813  aRefSeg->GetWidth() ) == 0 )
814  {
815  m_currentMarker = fillMarker( aRefSeg, NULL,
817  return false;
818  }
819  }
820  else if( aRefSeg->Type() == PCB_VIA_T )
821  {
822  if( ! area->GetDoNotAllowVias() )
823  continue;
824 
825  auto viaLayers = aRefSeg->GetLayerSet();
826 
827  if( !area->CommonLayerExists( viaLayers ) )
828  continue;
829 
830  if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 )
831  {
832  m_currentMarker = fillMarker( aRefSeg, NULL,
834  return false;
835  }
836  }
837  }
838 
839  return true;
840 }
841 
842 
843 bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit )
844 {
845  const static LSET all_cu = LSET::AllCuMask();
846 
847  LSET layerMask = aRefPad->GetLayerSet() & all_cu;
848 
849  /* used to test DRC pad to holes: this dummy pad has the size and shape of the hole
850  * to test pad to pad hole DRC, using the pad to pad DRC test function.
851  * Therefore, this dummy pad is a circle or an oval.
852  * A pad must have a parent because some functions expect a non null parent
853  * to find the parent board, and some other data
854  */
855  MODULE dummymodule( m_pcb ); // Creates a dummy parent
856  D_PAD dummypad( &dummymodule );
857 
858  // Ensure the hole is on all copper layers
859  dummypad.SetLayerSet( all_cu | dummypad.GetLayerSet() );
860 
861  // Use the minimal local clearance value for the dummy pad.
862  // The clearance of the active pad will be used as minimum distance to a hole
863  // (a value = 0 means use netclass value)
864  dummypad.SetLocalClearance( 1 );
865 
866  for( D_PAD** pad_list = aStart; pad_list<aEnd; ++pad_list )
867  {
868  D_PAD* pad = *pad_list;
869 
870  if( pad == aRefPad )
871  continue;
872 
873  // We can stop the test when pad->GetPosition().x > x_limit
874  // because the list is sorted by X values
875  if( pad->GetPosition().x > x_limit )
876  break;
877 
878  // No problem if pads which are on copper layers are on different copper layers,
879  // (pads can be only on a technical layer, to build complex pads)
880  // but their hole (if any ) can create DRC error because they are on all
881  // copper layers, so we test them
882  if( ( pad->GetLayerSet() & layerMask ) == 0 &&
883  ( pad->GetLayerSet() & all_cu ) != 0 &&
884  ( aRefPad->GetLayerSet() & all_cu ) != 0 )
885  {
886  // if holes are in the same location and have the same size and shape,
887  // this can be accepted
888  if( pad->GetPosition() == aRefPad->GetPosition()
889  && pad->GetDrillSize() == aRefPad->GetDrillSize()
890  && pad->GetDrillShape() == aRefPad->GetDrillShape() )
891  {
892  if( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
893  continue;
894 
895  // for oval holes: must also have the same orientation
896  if( pad->GetOrientation() == aRefPad->GetOrientation() )
897  continue;
898  }
899 
900  /* Here, we must test clearance between holes and pads
901  * dummy pad size and shape is adjusted to pad drill size and shape
902  */
903  if( pad->GetDrillSize().x )
904  {
905  // pad under testing has a hole, test this hole against pad reference
906  dummypad.SetPosition( pad->GetPosition() );
907  dummypad.SetSize( pad->GetDrillSize() );
908  dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
910  dummypad.SetOrientation( pad->GetOrientation() );
911 
912  if( !checkClearancePadToPad( aRefPad, &dummypad ) )
913  {
914  // here we have a drc error on pad!
915  m_currentMarker = fillMarker( pad, aRefPad,
917  return false;
918  }
919  }
920 
921  if( aRefPad->GetDrillSize().x ) // pad reference has a hole
922  {
923  dummypad.SetPosition( aRefPad->GetPosition() );
924  dummypad.SetSize( aRefPad->GetDrillSize() );
925  dummypad.SetShape( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
927  dummypad.SetOrientation( aRefPad->GetOrientation() );
928 
929  if( !checkClearancePadToPad( pad, &dummypad ) )
930  {
931  // here we have a drc error on aRefPad!
932  m_currentMarker = fillMarker( aRefPad, pad,
934  return false;
935  }
936  }
937 
938  continue;
939  }
940 
941  // The pad must be in a net (i.e pt_pad->GetNet() != 0 ),
942  // But no problem if pads have the same netcode (same net)
943  if( pad->GetNetCode() && ( aRefPad->GetNetCode() == pad->GetNetCode() ) )
944  continue;
945 
946  // if pads are from the same footprint
947  if( pad->GetParent() == aRefPad->GetParent() )
948  {
949  // and have the same pad number ( equivalent pads )
950 
951  // one can argue that this 2nd test is not necessary, that any
952  // two pads from a single module are acceptable. This 2nd test
953  // should eventually be a configuration option.
954  if( pad->PadNameEqual( aRefPad ) )
955  continue;
956  }
957 
958  // if either pad has no drill and is only on technical layers, not a clearance violation
959  if( ( ( pad->GetLayerSet() & layerMask ) == 0 && !pad->GetDrillSize().x ) ||
960  ( ( aRefPad->GetLayerSet() & layerMask ) == 0 && !aRefPad->GetDrillSize().x ) )
961  {
962  continue;
963  }
964 
965  if( !checkClearancePadToPad( aRefPad, pad ) )
966  {
967  // here we have a drc error!
969  return false;
970  }
971  }
972 
973  return true;
974 }
975 
976 
978 {
979  // Detects missing (or malformed) footprint courtyard,
980  // and for footprint with courtyard, courtyards overlap.
981  wxString msg;
982  bool success = true;
983 
984  // Update courtyard polygons, and test for missing courtyard definition:
985  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
986  {
987  bool is_ok = footprint->BuildPolyCourtyard();
988 
989  if( !is_ok && m_doFootprintOverlapping )
990  {
991  msg.Printf( _( "footprint '%s' has malformed courtyard" ),
992  footprint->GetReference().GetData() );
993  m_currentMarker = fillMarker( footprint->GetPosition(),
995  msg, m_currentMarker );
997  m_currentMarker = nullptr;
998  success = false;
999  }
1000 
1001  if( !m_doNoCourtyardDefined )
1002  continue;
1003 
1004  if( footprint->GetPolyCourtyardFront().OutlineCount() == 0 &&
1005  footprint->GetPolyCourtyardBack().OutlineCount() == 0 &&
1006  is_ok )
1007  {
1008  msg.Printf( _( "footprint '%s' has no courtyard defined" ),
1009  footprint->GetReference().GetData() );
1010  m_currentMarker = fillMarker( footprint->GetPosition(),
1012  msg, m_currentMarker );
1014  m_currentMarker = nullptr;
1015  success = false;
1016  }
1017  }
1018 
1020  return success;
1021 
1022  // Now test for overlapping on top layer:
1023  SHAPE_POLY_SET courtyard; // temporary storage of the courtyard of current footprint
1024 
1025  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1026  {
1027  if( footprint->GetPolyCourtyardFront().OutlineCount() == 0 )
1028  continue; // No courtyard defined
1029 
1030  for( MODULE* candidate = footprint->Next(); candidate; candidate = candidate->Next() )
1031  {
1032  if( candidate->GetPolyCourtyardFront().OutlineCount() == 0 )
1033  continue; // No courtyard defined
1034 
1035  courtyard.RemoveAllContours();
1036  courtyard.Append( footprint->GetPolyCourtyardFront() );
1037 
1038  // Build the common area between footprint and the candidate:
1039  courtyard.BooleanIntersection( candidate->GetPolyCourtyardFront(), SHAPE_POLY_SET::PM_FAST );
1040 
1041  // If no overlap, courtyard is empty (no common area).
1042  // Therefore if a common polygon exists, this is a DRC error
1043  if( courtyard.OutlineCount() )
1044  {
1045  //Overlap between footprint and candidate
1046  msg.Printf( _( "footprints '%s' and '%s' overlap on front (top) layer" ),
1047  footprint->GetReference().GetData(),
1048  candidate->GetReference().GetData() );
1049  VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 );
1050  wxPoint loc( pos.x, pos.y );
1053  m_currentMarker = nullptr;
1054  success = false;
1055  }
1056  }
1057  }
1058 
1059  // Test for overlapping on bottom layer:
1060  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1061  {
1062  if( footprint->GetPolyCourtyardBack().OutlineCount() == 0 )
1063  continue; // No courtyard defined
1064 
1065  for( MODULE* candidate = footprint->Next(); candidate; candidate = candidate->Next() )
1066  {
1067  if( candidate->GetPolyCourtyardBack().OutlineCount() == 0 )
1068  continue; // No courtyard defined
1069 
1070  courtyard.RemoveAllContours();
1071  courtyard.Append( footprint->GetPolyCourtyardBack() );
1072 
1073  // Build the common area between footprint and the candidate:
1074  courtyard.BooleanIntersection( candidate->GetPolyCourtyardBack(), SHAPE_POLY_SET::PM_FAST );
1075 
1076  // If no overlap, courtyard is empty (no common area).
1077  // Therefore if a common polygon exists, this is a DRC error
1078  if( courtyard.OutlineCount() )
1079  {
1080  //Overlap between footprint and candidate
1081  msg.Printf( _( "footprints '%s' and '%s' overlap on back (bottom) layer" ),
1082  footprint->GetReference().GetData(),
1083  candidate->GetReference().GetData() );
1084  VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 );
1085  wxPoint loc( pos.x, pos.y );
1088  m_currentMarker = nullptr;
1089  success = false;
1090  }
1091  }
1092  }
1093 
1094  return success;
1095 }
1096 
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
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:646
#define DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE
copper area has a net but no pads in nets, which is suspicious
Definition: drc_stuff.h:63
bool m_doNoCourtyardDefined
Definition: drc_stuff.h:172
#define DRCE_NETCLASS_CLEARANCE
netclass has Clearance < board.m_designSettings->m_TrackClearance
Definition: drc_stuff.h:72
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
bool m_doCreateRptFile
Definition: drc_stuff.h:170
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
#define OK_DRC
Definition: drc_stuff.h:35
void DestroyDRCDialog(int aReason)
Function DestroyDRCDialog deletes this ui dialog box and zeros out its pointer to remember the state ...
Definition: drc.cpp:99
bool PadNameEqual(const D_PAD *other) const
Definition: class_pad.h:207
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc_stuff.h:206
void UpdateDisplayedCounts()
Definition: dialog_drc.cpp:690
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:201
Class DRC_ITEM is a holder for a DRC (in Pcbnew) or ERC (in Eeschema) error item. ...
MARKER_PCB * fillMarker(const TRACK *aTrack, BOARD_ITEM *aItem, int aErrorCode, MARKER_PCB *fillMe)
Function fillMarker optionally creates a marker and fills it in with information, but does not add it...
Implementation of conversion functions that require both schematic and board internal units...
#define DRCE_PAD_NEAR_PAD1
pad too close to pad
Definition: drc_stuff.h:58
int m_ycliplo
Definition: drc_stuff.h:200
int Fill_All_Zones(wxWindow *aActiveWindow, bool aVerbose=true)
Function Fill_All_Zones Fill all zones on the board The old fillings are removed. ...
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:272
void testKeepoutAreas()
Definition: drc.cpp:616
void GetRptSettings(bool *aEnable, wxString &aFileName)
Definition: dialog_drc.cpp:164
MODULE * Next() const
Definition: class_module.h:100
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
int m_ycliphi
Definition: drc_stuff.h:202
static const int dist[10][10]
Definition: dist.cpp:57
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:262
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
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_stuff.h:194
BOARD * GetBoard() const
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:219
Classes to handle copper zones.
void ListUnconnectedPads()
Function ListUnconnectedPad gathers a list of all the unconnected pads and shows them in the dialog...
Definition: drc.cpp:315
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:381
iterator end()
#define DRCE_MISSING_COURTYARD_IN_FOOTPRINT
footprint has no courtyard defined
Definition: drc_stuff.h:84
#define DRCE_VIA_INSIDE_TEXT
Via in inside a text area.
Definition: drc_stuff.h:80
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
int OutlineCount() const
Returns the number of outlines in the set
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
#define DRCE_UNCONNECTED_ITEMS
items are unconnected
Definition: drc_stuff.h:41
#define DRCE_PAD_INSIDE_TEXT
Pad in inside a text area.
Definition: drc_stuff.h:82
wxPoint m_padToTestPos
Definition: drc_stuff.h:185
DRCLISTBOX * m_UnconnectedListBox
NETCLASS_MAP::const_iterator const_iterator
static const int delta[8][2]
Definition: solve.cpp:112
const wxPoint & GetEnd() const
Definition: class_track.h:118
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true) override
Executes the changes.
#define DRCE_TRACK_INSIDE_KEEPOUT
Track in inside a keepout area.
Definition: drc_stuff.h:78
Functions relatives to tracks, vias and segments used to fill zones.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:107
void testTexts()
Definition: drc.cpp:670
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:154
bool doTrackKeepoutDrc(TRACK *aRefSeg)
Function doTrackKeepoutDrc tests the current segment or via.
Definition: drc.cpp:794
BOARD * m_pcb
Definition: drc_stuff.h:205
bool m_doFootprintOverlapping
Definition: drc_stuff.h:171
#define BAD_DRC
Definition: drc_stuff.h:36
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:672
const wxPoint & GetPosition() const override
Definition: class_track.h:112
#define DRCE_TRACK_INSIDE_TEXT
Track in inside a text area.
Definition: drc_stuff.h:81
void addMarkerToPcb(MARKER_PCB *aMarker)
Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism.
Definition: drc.cpp:92
bool m_doKeepoutTest
Definition: drc_stuff.h:169
Class LSET is a set of PCB_LAYER_IDs.
bool m_doZonesTest
Definition: drc_stuff.h:168
iterator begin()
Class NETCLASSES is a container for NETCLASS instances.
#define DRCE_NETCLASS_uVIADRILLSIZE
netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill
Definition: drc_stuff.h:76
#define DRCE_VIA_INSIDE_KEEPOUT
Via in inside a keepout area.
Definition: drc_stuff.h:77
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:271
void testZones()
Definition: drc.cpp:578
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:784
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:586
Class SHAPE_POLY_SET.
DRCLISTBOX * m_ClearanceListBox
bool m_abortDRC
Definition: drc_stuff.h:178
bool m_drcInProgress
Definition: drc_stuff.h:179
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:121
const wxPoint & GetPosition() const override
Definition: class_pad.h:220
int m_TrackMinWidth
track min value for width ((min copper size value
DRC(PCB_EDIT_FRAME *aPcbWindow)
Definition: drc.cpp:115
int m_ViasMinSize
vias (not micro vias) min diameter
void updatePointers()
Function updatePointers is a private helper function used to update needed pointers from the one poin...
Definition: drc.cpp:324
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:395
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:532
void SetSize(const wxSize &aSize)
Definition: class_pad.h:268
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
bool doPadToPadsDrc(D_PAD *aRefPad, D_PAD **aStart, D_PAD **aEnd, int x_limit)
Function doPadToPadsDrc tests the clearance between aRefPad and other pads.
Definition: drc.cpp:843
int m_xcliphi
Definition: drc_stuff.h:201
int m_MicroViasMinSize
micro vias (not vias) min diameter
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc_stuff.h:204
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset intersection For aFastMode meaning, see function booleanOp ...
bool m_doPad2PadTest
Definition: drc_stuff.h:166
void testPad2Pad()
Definition: drc.cpp:454
bool Show(bool show) override
bool doEdgeZoneDrc(ZONE_CONTAINER *aArea, int aCornerIndex)
Function doEdgeZoneDrc tests a segment in ZONE_CONTAINER * aArea: Test Edge inside other areas Test E...
Pad object description.
void SetLocalClearance(int aClearance)
Definition: class_pad.h:407
#define FmtVal(x)
friend class DIALOG_DRC_CONTROL
Definition: drc_stuff.h:160
bool checkClearancePadToPad(D_PAD *aRefPad, D_PAD *aPad)
Function checkClearancePadToPad.
int GetNetCode() const
Function GetNetCode.
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:176
Definition: seg.h:37
bool doFootprintOverlappingDrc()
Function doFootprintOverlappingDrc tests for footprint courtyard overlaps.
Definition: drc.cpp:977
bool checkClearanceSegmToPad(const D_PAD *aPad, int aSegmentWidth, int aMinDist)
Function checkClearanceSegmToPad 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_stuff.h:186
TOOL_MANAGER * GetToolManager() const
Function GetToolManager returns the tool manager instance, if any.
Definition: draw_frame.h:877
void SetLayerSet(LSET aLayerMask)
Definition: class_pad.h:394
#define DRCE_NETCLASS_uVIASIZE
netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize
Definition: drc_stuff.h:75
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.cpp:188
bool GetDoNotAllowTracks() const
Definition: class_zone.h:675
bool testNetClasses()
Function testNetClasses goes through each NETCLASS and verifies that its clearance, via size, track width, and track clearance are larger than those in board.m_designSettings.
Definition: drc.cpp:431
void testTracks(wxWindow *aActiveWindow, bool aShowProgressBar)
Function testTracks performs the DRC on all tracks.
Definition: drc.cpp:493
#define DRCE_OVERLAPPING_FOOTPRINTS
footprint courtyards overlap
Definition: drc_stuff.h:83
TRACK * Next() const
Definition: class_track.h:98
void ShowDRCDialog(wxWindow *aParent=NULL)
Function ShowDRCDialog opens a dialog and prompts the user, then if a test run button is clicked...
Definition: drc.cpp:58
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:982
wxString m_rptFilename
Definition: drc_stuff.h:174
bool GetDoNotAllowVias() const
Definition: class_zone.h:674
DLIST< MODULE > m_Modules
Definition: class_board.h:245
int GetWidth() const
Definition: class_track.h:115
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:493
#define DRCE_MALFORMED_COURTYARD_IN_FOOTPRINT
footprint has a courtyard but malformed
Definition: drc_stuff.h:85
NETCLASSPTR GetDefault() const
Function GetDefault.
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:375
#define DRCE_NETCLASS_TRACKWIDTH
netclass has TrackWidth < board.m_designSettings->m_TrackMinWidth
Definition: drc_stuff.h:71
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_pad.cpp:546
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.
int Drc(TRACK *aRefSeg, TRACK *aList)
Function Drc tests the current segment and returns the result and displays the error in the status pa...
Definition: drc.cpp:155
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:108
bool doTrackDrc(TRACK *aRefSeg, TRACK *aStart, bool doPads=true)
Function DoTrackDrc tests the current segment.
DLIST< TRACK > m_Track
Definition: class_board.h:246
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
#define DRCE_NETCLASS_VIASIZE
netclass has ViaSize < board.m_designSettings->m_ViasMinSize
Definition: drc_stuff.h:73
Module description (excepted pads)
int m_MicroViasMinDrill
micro vias (not vias) min drill diameter
int Test_Drc_Areas_Outlines_To_Areas_Outlines(ZONE_CONTAINER *aArea_To_Examine, bool aCreate_Markers)
Function Test_Drc_Areas_Outlines_To_Areas_Outlines tests area outlines for DRC: Tests areas inside ot...
DRC_LIST m_unconnected
list of unconnected pads, as DRC_ITEMs
Definition: drc_stuff.h:208
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:637
~DRC()
Definition: drc.cpp:147
void testUnconnected()
Definition: drc.cpp:548
void RunTests(wxTextCtrl *aMessages=NULL)
Function RunTests will actually run all the tests specified with a previous call to SetSettings() ...
Definition: drc.cpp:194
int m_xcliplo
Definition: drc_stuff.h:199
bool doNetClass(std::shared_ptr< NETCLASS > aNetClass, wxString &msg)
Definition: drc.cpp:339
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:290
bool m_doUnconnectedTest
Definition: drc_stuff.h:167
double m_segmAngle
Definition: drc_stuff.h:193
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:251
void SetRptSettings(bool aEnable, const wxString &aFileName)
Enable/disable the report file creation.
Definition: dialog_drc.cpp:156
NETCLASSES m_NetClasses
List of current netclasses. There is always the default netclass.
#define DRCE_HOLE_NEAR_PAD
hole too close to pad
Definition: drc_stuff.h:64
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) ...
#define DRCE_NETCLASS_VIADRILLSIZE
netclass has ViaDrillSize < board.m_designSettings->m_ViasMinDrill
Definition: drc_stuff.h:74