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