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  BOARD_COMMIT commit( m_pcbEditorFrame );
101  commit.Add( aMarker );
102  commit.Push( wxEmptyString, false, false );
103 }
104 
105 
106 void DRC::DestroyDRCDialog( int aReason )
107 {
108  if( m_drcDialog )
109  {
110  if( aReason == wxID_OK )
111  {
112  // if user clicked OK, save his choices in this DRC object.
114  }
115 
116  m_drcDialog->Destroy();
117  m_drcDialog = NULL;
118  }
119 }
120 
121 
122 DRC::DRC( PCB_EDIT_FRAME* aPcbWindow )
123 {
124  m_pcbEditorFrame = aPcbWindow;
125  m_pcb = aPcbWindow->GetBoard();
126  m_drcDialog = NULL;
127 
128  // establish initial values for everything:
129  m_doPad2PadTest = true; // enable pad to pad clearance tests
130  m_doUnconnectedTest = true; // enable unconnected tests
131  m_doZonesTest = true; // enable zone to items clearance tests
132  m_doKeepoutTest = true; // enable keepout areas to items clearance tests
133  m_doFootprintOverlapping = true; // enable courtyards areas overlap tests
134  m_doNoCourtyardDefined = true; // enable missing courtyard in footprint warning
135  m_abortDRC = false;
136  m_drcInProgress = false;
137  m_refillZones = false; // Only fill zones if requested by user.
138  m_reportAllTrackErrors = false;
139  m_doCreateRptFile = false;
140 
141  // m_rptFilename set to empty by its constructor
142 
143  m_currentMarker = NULL;
144 
145  m_segmAngle = 0;
146  m_segmLength = 0;
147 
148  m_xcliplo = 0;
149  m_ycliplo = 0;
150  m_xcliphi = 0;
151  m_ycliphi = 0;
152 }
153 
154 
156 {
157  // maybe someday look at pointainer.h <- google for "pointainer.h"
158  for( unsigned i = 0; i<m_unconnected.size(); ++i )
159  delete m_unconnected[i];
160 }
161 
162 
163 int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
164 {
165  updatePointers();
166 
167  if( !doTrackDrc( aRefSegm, aList, true ) )
168  {
169  if( m_currentMarker )
171 
172  return BAD_DRC;
173  }
174 
175  if( !doTrackKeepoutDrc( aRefSegm ) )
176  {
177  wxASSERT( m_currentMarker );
178 
180  return BAD_DRC;
181  }
182 
183  return OK_DRC;
184 }
185 
186 
187 int DRC::TestZoneToZoneOutline( ZONE_CONTAINER* aZone, bool aCreateMarkers )
188 {
189  BOARD* board = m_pcbEditorFrame->GetBoard();
190  BOARD_COMMIT commit( m_pcbEditorFrame );
191  int nerrors = 0;
192 
193  // iterate through all areas
194  for( int ia = 0; ia < board->GetAreaCount(); ia++ )
195  {
196  ZONE_CONTAINER* zoneRef = board->GetArea( ia );
197  SHAPE_POLY_SET refSmoothedPoly;
198 
199  zoneRef->BuildSmoothedPoly( refSmoothedPoly );
200 
201  if( !zoneRef->IsOnCopperLayer() )
202  continue;
203 
204  // When testing only a single area, skip all others
205  if( aZone && ( aZone != zoneRef) )
206  continue;
207 
208  for( int ia2 = 0; ia2 < board->GetAreaCount(); ia2++ )
209  {
210  ZONE_CONTAINER* zoneToTest = board->GetArea( ia2 );
211  SHAPE_POLY_SET testSmoothedPoly;
212 
213  zoneToTest->BuildSmoothedPoly( testSmoothedPoly );
214 
215  if( zoneRef == zoneToTest )
216  continue;
217 
218  // test for same layer
219  if( zoneRef->GetLayer() != zoneToTest->GetLayer() )
220  continue;
221 
222  // Test for same net
223  if( zoneRef->GetNetCode() == zoneToTest->GetNetCode() && zoneRef->GetNetCode() >= 0 )
224  continue;
225 
226  // test for different priorities
227  if( zoneRef->GetPriority() != zoneToTest->GetPriority() )
228  continue;
229 
230  // test for different types
231  if( zoneRef->GetIsKeepout() != zoneToTest->GetIsKeepout() )
232  continue;
233 
234  // Examine a candidate zone: compare zoneToTest to zoneRef
235 
236  // Get clearance used in zone to zone test. The policy used to
237  // obtain that value is now part of the zone object itself by way of
238  // ZONE_CONTAINER::GetClearance().
239  int zone2zoneClearance = zoneRef->GetClearance( zoneToTest );
240 
241  // Keepout areas have no clearance, so set zone2zoneClearance to 1
242  // ( zone2zoneClearance = 0 can create problems in test functions)
243  if( zoneRef->GetIsKeepout() )
244  zone2zoneClearance = 1;
245 
246  // test for some corners of zoneRef inside zoneToTest
247  for( auto iterator = refSmoothedPoly.IterateWithHoles(); iterator; iterator++ )
248  {
249  VECTOR2I currentVertex = *iterator;
250 
251  if( testSmoothedPoly.Contains( currentVertex ) )
252  {
253  // COPPERAREA_COPPERAREA error: copper area ref corner inside copper area
254  if( aCreateMarkers )
255  {
256  wxPoint pt( currentVertex.x, currentVertex.y );
257  wxString msg1 = zoneRef->GetSelectMenuText();
258  wxString msg2 = zoneToTest->GetSelectMenuText();
260  pt, msg1, pt, msg2, pt );
261  commit.Add( marker );
262  }
263 
264  nerrors++;
265  }
266  }
267 
268  // test for some corners of zoneToTest inside zoneRef
269  for( auto iterator = testSmoothedPoly.IterateWithHoles(); iterator; iterator++ )
270  {
271  VECTOR2I currentVertex = *iterator;
272 
273  if( refSmoothedPoly.Contains( currentVertex ) )
274  {
275  // COPPERAREA_COPPERAREA error: copper area corner inside copper area ref
276  if( aCreateMarkers )
277  {
278  wxPoint pt( currentVertex.x, currentVertex.y );
279  wxString msg1 = zoneToTest->GetSelectMenuText();
280  wxString msg2 = zoneRef->GetSelectMenuText();
282  pt, msg1, pt, msg2, pt );
283  commit.Add( marker );
284  }
285 
286  nerrors++;
287  }
288  }
289 
290  // Iterate through all the segments of refSmoothedPoly
291  for( auto refIt = refSmoothedPoly.IterateSegmentsWithHoles(); refIt; refIt++ )
292  {
293  // Build ref segment
294  SEG refSegment = *refIt;
295 
296  // Iterate through all the segments in testSmoothedPoly
297  for( auto testIt = testSmoothedPoly.IterateSegmentsWithHoles(); testIt; testIt++ )
298  {
299  // Build test segment
300  SEG testSegment = *testIt;
301  wxPoint pt;
302 
303  int ax1, ay1, ax2, ay2;
304  ax1 = refSegment.A.x;
305  ay1 = refSegment.A.y;
306  ax2 = refSegment.B.x;
307  ay2 = refSegment.B.y;
308 
309  int bx1, by1, bx2, by2;
310  bx1 = testSegment.A.x;
311  by1 = testSegment.A.y;
312  bx2 = testSegment.B.x;
313  by2 = testSegment.B.y;
314 
315  int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
316  0,
317  ax1, ay1, ax2, ay2,
318  0,
319  zone2zoneClearance,
320  &pt.x, &pt.y );
321 
322  if( d < zone2zoneClearance )
323  {
324  // COPPERAREA_COPPERAREA error : intersect or too close
325  if( aCreateMarkers )
326  {
327  wxString msg1 = zoneRef->GetSelectMenuText();
328  wxString msg2 = zoneToTest->GetSelectMenuText();
330  pt, msg1, pt, msg2, pt );
331  commit.Add( marker );
332  }
333 
334  nerrors++;
335  }
336  }
337  }
338  }
339  }
340 
341  if( aCreateMarkers )
342  commit.Push( wxEmptyString, false, false );
343 
344  return nerrors;
345 }
346 
347 
348 int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex )
349 {
350  updatePointers();
351 
352  if( !doEdgeZoneDrc( aArea, aCornerIndex ) )
353  {
354  wxASSERT( m_currentMarker );
356  return BAD_DRC;
357  }
358 
359  return OK_DRC;
360 }
361 
362 
363 void DRC::RunTests( wxTextCtrl* aMessages )
364 {
365  // be sure m_pcb is the current board, not a old one
366  // ( the board can be reloaded )
368 
369  // someone should have cleared the two lists before calling this.
370 
371  if( !testNetClasses() )
372  {
373  // testing the netclasses is a special case because if the netclasses
374  // do not pass the BOARD_DESIGN_SETTINGS checks, then every member of a net
375  // class (a NET) will cause its items such as tracks, vias, and pads
376  // to also fail. So quit after *all* netclass errors have been reported.
377  if( aMessages )
378  aMessages->AppendText( _( "Aborting\n" ) );
379 
380  // update the m_drcDialog listboxes
381  updatePointers();
382 
383  return;
384  }
385 
386  // test pad to pad clearances, nothing to do with tracks, vias or zones.
387  if( m_doPad2PadTest )
388  {
389  if( aMessages )
390  {
391  aMessages->AppendText( _( "Pad clearances...\n" ) );
392  wxSafeYield();
393  }
394 
395  testPad2Pad();
396  }
397 
398  // test track and via clearances to other tracks, pads, and vias
399  if( aMessages )
400  {
401  aMessages->AppendText( _( "Track clearances...\n" ) );
402  wxSafeYield();
403  }
404 
405  testTracks( aMessages ? aMessages->GetParent() : m_pcbEditorFrame, true );
406 
407  // caller (a wxTopLevelFrame) is the wxDialog or the Pcb Editor frame that call DRC:
408  wxWindow* caller = aMessages ? aMessages->GetParent() : m_pcbEditorFrame;
409 
410  if( m_refillZones )
411  {
412  aMessages->AppendText( _( "Refilling all zones...\n" ) );
413  m_pcbEditorFrame->Fill_All_Zones( caller );
414  }
415  else
416  {
417  aMessages->AppendText( _( "Checking zone fills...\n" ) );
419  }
420 
421  // test zone clearances to other zones
422  if( aMessages )
423  {
424  aMessages->AppendText( _( "Zone to zone clearances...\n" ) );
425  wxSafeYield();
426  }
427 
428  testZones();
429 
430  // find and gather unconnected pads.
431  if( m_doUnconnectedTest )
432  {
433  if( aMessages )
434  {
435  aMessages->AppendText( _( "Unconnected pads...\n" ) );
436  aMessages->Refresh();
437  }
438 
439  testUnconnected();
440  }
441 
442  // find and gather vias, tracks, pads inside keepout areas.
443  if( m_doKeepoutTest )
444  {
445  if( aMessages )
446  {
447  aMessages->AppendText( _( "Keepout areas ...\n" ) );
448  aMessages->Refresh();
449  }
450 
452  }
453 
454  // find and gather vias, tracks, pads inside text boxes.
455  if( aMessages )
456  {
457  aMessages->AppendText( _( "Test texts...\n" ) );
458  wxSafeYield();
459  }
460 
461  testTexts();
462 
463  // find overlapping courtyard ares.
465  {
466  if( aMessages )
467  {
468  aMessages->AppendText( _( "Courtyard areas...\n" ) );
469  aMessages->Refresh();
470  }
471 
473  }
474 
475  // update the m_drcDialog listboxes
476  updatePointers();
477 
478  if( aMessages )
479  {
480  // no newline on this one because it is last, don't want the window
481  // to unnecessarily scroll.
482  aMessages->AppendText( _( "Finished" ) );
483  }
484 }
485 
486 
488 {
489  testUnconnected();
490 
491  // update the m_drcDialog listboxes
492  updatePointers();
493 }
494 
495 
497 {
498  // update my pointers, m_pcbEditorFrame is the only unchangeable one
500 
501  if( m_drcDialog ) // Use diag list boxes only in DRC dialog
502  {
505 
507  }
508 }
509 
510 
511 bool DRC::doNetClass( const NETCLASSPTR& nc, wxString& msg )
512 {
513  bool ret = true;
514 
516 
517 #define FmtVal( x ) GetChars( StringFromValue( g_UserUnit, x ) )
518 
519 #if 0 // set to 1 when (if...) BOARD_DESIGN_SETTINGS has a m_MinClearance value
520  if( nc->GetClearance() < g.m_MinClearance )
521  {
522  msg.Printf( _( "NETCLASS: \"%s\" has Clearance:%s which is less than global:%s" ),
523  GetChars( nc->GetName() ),
524  FmtVal( nc->GetClearance() ),
525  FmtVal( g.m_TrackClearance )
526  );
527 
529  m_currentMarker = nullptr;
530  ret = false;
531  }
532 #endif
533 
534  if( nc->GetTrackWidth() < g.m_TrackMinWidth )
535  {
536  msg.Printf( _( "NETCLASS: \"%s\" has TrackWidth:%s which is less than global:%s" ),
537  GetChars( nc->GetName() ),
538  FmtVal( nc->GetTrackWidth() ),
540  );
541 
543  m_currentMarker = nullptr;
544  ret = false;
545  }
546 
547  if( nc->GetViaDiameter() < g.m_ViasMinSize )
548  {
549  msg.Printf( _( "NETCLASS: \"%s\" has Via Dia:%s which is less than global:%s" ),
550  GetChars( nc->GetName() ),
551  FmtVal( nc->GetViaDiameter() ),
552  FmtVal( g.m_ViasMinSize )
553  );
554 
556  m_currentMarker = nullptr;
557  ret = false;
558  }
559 
560  if( nc->GetViaDrill() < g.m_ViasMinDrill )
561  {
562  msg.Printf( _( "NETCLASS: \"%s\" has Via Drill:%s which is less than global:%s" ),
563  GetChars( nc->GetName() ),
564  FmtVal( nc->GetViaDrill() ),
566  );
567 
569  m_currentMarker = nullptr;
570  ret = false;
571  }
572 
573  if( nc->GetuViaDiameter() < g.m_MicroViasMinSize )
574  {
575  msg.Printf( _( "NETCLASS: \"%s\" has uVia Dia:%s which is less than global:%s" ),
576  GetChars( nc->GetName() ),
577  FmtVal( nc->GetuViaDiameter() ),
579  );
580 
582  m_currentMarker = nullptr;
583  ret = false;
584  }
585 
586  if( nc->GetuViaDrill() < g.m_MicroViasMinDrill )
587  {
588  msg.Printf( _( "NETCLASS: \"%s\" has uVia Drill:%s which is less than global:%s" ),
589  GetChars( nc->GetName() ),
590  FmtVal( nc->GetuViaDrill() ),
592  );
593 
595  m_currentMarker = nullptr;
596  ret = false;
597  }
598 
599  return ret;
600 }
601 
602 
604 {
605  bool ret = true;
606 
608 
609  wxString msg; // construct this only once here, not in a loop, since somewhat expensive.
610 
611  if( !doNetClass( netclasses.GetDefault(), msg ) )
612  ret = false;
613 
614  for( NETCLASSES::const_iterator i = netclasses.begin(); i != netclasses.end(); ++i )
615  {
616  NETCLASSPTR nc = i->second;
617 
618  if( !doNetClass( nc, msg ) )
619  ret = false;
620  }
621 
622  return ret;
623 }
624 
625 
627 {
628  std::vector<D_PAD*> sortedPads;
629 
630  m_pcb->GetSortedPadListByXthenYCoord( sortedPads );
631 
632  // find the max size of the pads (used to stop the test)
633  int max_size = 0;
634 
635  for( unsigned i = 0; i < sortedPads.size(); ++i )
636  {
637  D_PAD* pad = sortedPads[i];
638 
639  // GetBoundingRadius() is the radius of the minimum sized circle fully containing the pad
640  int radius = pad->GetBoundingRadius();
641 
642  if( radius > max_size )
643  max_size = radius;
644  }
645 
646  // Test the pads
647  D_PAD** listEnd = &sortedPads[ sortedPads.size() ];
648 
649  for( unsigned i = 0; i< sortedPads.size(); ++i )
650  {
651  D_PAD* pad = sortedPads[i];
652 
653  int x_limit = max_size + pad->GetClearance() +
654  pad->GetBoundingRadius() + pad->GetPosition().x;
655 
656  if( !doPadToPadsDrc( pad, &sortedPads[i], listEnd, x_limit ) )
657  {
658  wxASSERT( m_currentMarker );
660  m_currentMarker = nullptr;
661  }
662  }
663 }
664 
665 
666 void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
667 {
668  wxProgressDialog * progressDialog = NULL;
669  const int delta = 500; // This is the number of tests between 2 calls to the
670  // progress bar
671  int count = 0;
672 
673  for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() )
674  count++;
675 
676  int deltamax = count/delta;
677 
678  if( aShowProgressBar && deltamax > 3 )
679  {
680  // Do not use wxPD_APP_MODAL style here: it is not necessary and create issues
681  // on OSX
682  progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString,
683  deltamax, aActiveWindow,
684  wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME );
685  progressDialog->Update( 0, wxEmptyString );
686  }
687 
688  int ii = 0;
689  count = 0;
690 
691  for( TRACK* segm = m_pcb->m_Track; segm; segm = segm->Next() )
692  {
693  if( ii++ > delta )
694  {
695  ii = 0;
696  count++;
697 
698  if( progressDialog )
699  {
700  if( !progressDialog->Update( count, wxEmptyString ) )
701  break; // Aborted by user
702 #ifdef __WXMAC__
703  // Work around a dialog z-order issue on OS X
704  if( count == deltamax )
705  aActiveWindow->Raise();
706 #endif
707  }
708  }
709 
710  if( !doTrackDrc( segm, segm->Next(), true ) )
711  {
712  if( m_currentMarker )
713  {
715  m_currentMarker = nullptr;
716  }
717  }
718  }
719 
720  if( progressDialog )
721  progressDialog->Destroy();
722 }
723 
724 
726 {
727 
728  auto connectivity = m_pcb->GetConnectivity();
729 
730  connectivity->Clear();
731  connectivity->Build( m_pcb ); // just in case. This really needs to be reliable.
732  connectivity->RecalculateRatsnest();
733 
734  std::vector<CN_EDGE> edges;
735  connectivity->GetUnconnectedEdges( edges );
736 
737  for( const auto& edge : edges )
738  {
739  wxString t_src = edge.GetSourceNode()->Parent()->GetSelectMenuText();
740  wxString t_dst = edge.GetTargetNode()->Parent()->GetSelectMenuText();
741  auto src = edge.GetSourcePos();
742  auto dst = edge.GetTargetPos();
743 
744 
745  DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_ITEMS,
746  t_src,
747  t_dst,
748  wxPoint( src.x, src.y ), wxPoint( dst.x, dst.y ) );
749  m_unconnected.push_back( uncItem );
750 
751  }
752 }
753 
754 
756 {
757  // Test copper areas for valid netcodes
758  // if a netcode is < 0 the netname was not found when reading a netlist
759  // if a netcode is == 0 the netname is void, and the zone is not connected.
760  // This is allowed, but i am not sure this is a good idea
761  //
762  // In recent Pcbnew versions, the netcode is always >= 0, but an internal net name
763  // is stored, and initialized from the file or the zone properties editor.
764  // if it differs from the net name from net code, there is a DRC issue
765  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
766  {
767  ZONE_CONTAINER* test_area = m_pcb->GetArea( ii );
768 
769  if( !test_area->IsOnCopperLayer() )
770  continue;
771 
772  int netcode = test_area->GetNetCode();
773 
774  // a netcode < 0 or > 0 and no pad in net is a error or strange
775  // perhaps a "dead" net, which happens when all pads in this net were removed
776  // Remark: a netcode < 0 should not happen (this is more a bug somewhere)
777  int pads_in_net = (test_area->GetNetCode() > 0) ?
778  m_pcb->GetConnectivity()->GetPadCount( test_area->GetNetCode() ) : 1;
779 
780  if( ( netcode < 0 ) || pads_in_net == 0 )
781  {
782  addMarkerToPcb( fillMarker( test_area,
784  m_currentMarker = nullptr;
785  }
786  }
787 
788  // Test copper areas outlines, and create markers when needed
789  TestZoneToZoneOutline( NULL, true );
790 }
791 
792 
794 {
795  // Test keepout areas for vias, tracks and pads inside keepout areas
796  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
797  {
798  ZONE_CONTAINER* area = m_pcb->GetArea( ii );
799 
800  if( !area->GetIsKeepout() )
801  {
802  continue;
803  }
804 
805  for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() )
806  {
807  if( segm->Type() == PCB_TRACE_T )
808  {
809  if( !area->GetDoNotAllowTracks() )
810  continue;
811 
812  // Ignore if the keepout zone is not on the same layer
813  if( !area->IsOnLayer( segm->GetLayer() ) )
814  continue;
815 
816  if( area->Outline()->Distance( SEG( segm->GetStart(), segm->GetEnd() ),
817  segm->GetWidth() ) == 0 )
818  {
819  addMarkerToPcb( fillMarker( segm, NULL,
821  m_currentMarker = nullptr;
822  }
823  }
824  else if( segm->Type() == PCB_VIA_T )
825  {
826  if( ! area->GetDoNotAllowVias() )
827  continue;
828 
829  auto viaLayers = segm->GetLayerSet();
830 
831  if( !area->CommonLayerExists( viaLayers ) )
832  continue;
833 
834  if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 )
835  {
836  addMarkerToPcb( fillMarker( segm, NULL,
838  m_currentMarker = nullptr;
839  }
840  }
841  }
842  // Test pads: TODO
843  }
844 }
845 
846 
848 {
849  std::vector<wxPoint> textShape; // a buffer to store the text shape (set of segments)
850  std::vector<D_PAD*> padList = m_pcb->GetPads();
851 
852  // Test text areas for vias, tracks and pads inside text areas
853  for( auto item : m_pcb->Drawings() )
854  {
855  // Drc test only items on copper layers
856  if( !IsCopperLayer( item->GetLayer() ) )
857  continue;
858 
859  // only texts on copper layers are tested
860  if( item->Type() != PCB_TEXT_T )
861  continue;
862 
863  textShape.clear();
864 
865  // So far the bounding box makes up the text-area
866  TEXTE_PCB* text = (TEXTE_PCB*) item;
867  text->TransformTextShapeToSegmentList( textShape );
868 
869  if( textShape.size() == 0 ) // Should not happen (empty text?)
870  continue;
871 
872  for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
873  {
874  if( !track->IsOnLayer( item->GetLayer() ) )
875  continue;
876 
877  // Test the distance between each segment and the current track/via
878  int min_dist = ( track->GetWidth() + text->GetThickness() ) /2 +
879  track->GetClearance(NULL);
880 
881  if( track->Type() == PCB_TRACE_T )
882  {
883  SEG segref( track->GetStart(), track->GetEnd() );
884 
885  // Error condition: Distance between text segment and track segment is
886  // smaller than the clearance of the segment
887  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
888  {
889  SEG segtest( textShape[jj], textShape[jj+1] );
890  int dist = segref.Distance( segtest );
891 
892  if( dist < min_dist )
893  {
894  addMarkerToPcb( fillMarker( track, text,
896  m_currentMarker ) );
897  m_currentMarker = nullptr;
898  break;
899  }
900  }
901  }
902  else if( track->Type() == PCB_VIA_T )
903  {
904  // Error condition: Distance between text segment and via is
905  // smaller than the clearance of the via
906  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
907  {
908  SEG segtest( textShape[jj], textShape[jj+1] );
909 
910  if( segtest.PointCloserThan( track->GetPosition(), min_dist ) )
911  {
912  addMarkerToPcb( fillMarker( track, text,
914  m_currentMarker = nullptr;
915  break;
916  }
917  }
918  }
919  }
920 
921  // Test pads
922  for( unsigned ii = 0; ii < padList.size(); ii++ )
923  {
924  D_PAD* pad = padList[ii];
925 
926  if( !pad->IsOnLayer( item->GetLayer() ) )
927  continue;
928 
929  wxPoint shape_pos = pad->ShapePos();
930 
931  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
932  {
933  /* In order to make some calculations more easier or faster,
934  * pads and tracks coordinates will be made relative
935  * to the segment origin
936  */
937  wxPoint origin = textShape[jj]; // origin will be the origin of other coordinates
938  m_segmEnd = textShape[jj+1] - origin;
940  m_segmAngle = 0;
941 
942  // for a non horizontal or vertical segment Compute the segment angle
943  // in tenths of degrees and its length
944  if( delta.x || delta.y ) // delta.x == delta.y == 0 for vias
945  {
946  // Compute the segment angle in 0,1 degrees
947  m_segmAngle = ArcTangente( delta.y, delta.x );
948 
949  // Compute the segment length: we build an equivalent rotated segment,
950  // this segment is horizontal, therefore dx = length
951  RotatePoint( &delta, m_segmAngle ); // delta.x = length, delta.y = 0
952  }
953 
954  m_segmLength = delta.x;
955  m_padToTestPos = shape_pos - origin;
956 
957  if( !checkClearanceSegmToPad( pad, text->GetThickness(),
958  pad->GetClearance(NULL) ) )
959  {
960  addMarkerToPcb( fillMarker( pad, text,
962  m_currentMarker = nullptr;
963  break;
964  }
965  }
966  }
967  }
968 }
969 
970 
972 {
973  // Test keepout areas for vias, tracks and pads inside keepout areas
974  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
975  {
976  ZONE_CONTAINER* area = m_pcb->GetArea( ii );
977 
978  if( !area->GetIsKeepout() )
979  continue;
980 
981  if( aRefSeg->Type() == PCB_TRACE_T )
982  {
983  if( !area->GetDoNotAllowTracks() )
984  continue;
985 
986  if( !area->IsOnLayer( aRefSeg->GetLayer() ) )
987  continue;
988 
989  if( area->Outline()->Distance( SEG( aRefSeg->GetStart(), aRefSeg->GetEnd() ),
990  aRefSeg->GetWidth() ) == 0 )
991  {
992  m_currentMarker = fillMarker( aRefSeg, NULL,
994  return false;
995  }
996  }
997  else if( aRefSeg->Type() == PCB_VIA_T )
998  {
999  if( !area->GetDoNotAllowVias() )
1000  continue;
1001 
1002  auto viaLayers = aRefSeg->GetLayerSet();
1003 
1004  if( !area->CommonLayerExists( viaLayers ) )
1005  continue;
1006 
1007  if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 )
1008  {
1009  m_currentMarker = fillMarker( aRefSeg, NULL,
1011  return false;
1012  }
1013  }
1014  }
1015 
1016  return true;
1017 }
1018 
1019 
1020 bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_limit )
1021 {
1022  const static LSET all_cu = LSET::AllCuMask();
1023 
1024  LSET layerMask = aRefPad->GetLayerSet() & all_cu;
1025 
1026  /* used to test DRC pad to holes: this dummy pad has the size and shape of the hole
1027  * to test pad to pad hole DRC, using the pad to pad DRC test function.
1028  * Therefore, this dummy pad is a circle or an oval.
1029  * A pad must have a parent because some functions expect a non null parent
1030  * to find the parent board, and some other data
1031  */
1032  MODULE dummymodule( m_pcb ); // Creates a dummy parent
1033  D_PAD dummypad( &dummymodule );
1034 
1035  // Ensure the hole is on all copper layers
1036  dummypad.SetLayerSet( all_cu | dummypad.GetLayerSet() );
1037 
1038  // Use the minimal local clearance value for the dummy pad.
1039  // The clearance of the active pad will be used as minimum distance to a hole
1040  // (a value = 0 means use netclass value)
1041  dummypad.SetLocalClearance( 1 );
1042 
1043  for( D_PAD** pad_list = aStart; pad_list<aEnd; ++pad_list )
1044  {
1045  D_PAD* pad = *pad_list;
1046 
1047  if( pad == aRefPad )
1048  continue;
1049 
1050  // We can stop the test when pad->GetPosition().x > x_limit
1051  // because the list is sorted by X values
1052  if( pad->GetPosition().x > x_limit )
1053  break;
1054 
1055  // No problem if pads which are on copper layers are on different copper layers,
1056  // (pads can be only on a technical layer, to build complex pads)
1057  // but their hole (if any ) can create DRC error because they are on all
1058  // copper layers, so we test them
1059  if( ( pad->GetLayerSet() & layerMask ) == 0 &&
1060  ( pad->GetLayerSet() & all_cu ) != 0 &&
1061  ( aRefPad->GetLayerSet() & all_cu ) != 0 )
1062  {
1063  // if holes are in the same location and have the same size and shape,
1064  // this can be accepted
1065  if( pad->GetPosition() == aRefPad->GetPosition()
1066  && pad->GetDrillSize() == aRefPad->GetDrillSize()
1067  && pad->GetDrillShape() == aRefPad->GetDrillShape() )
1068  {
1069  if( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
1070  continue;
1071 
1072  // for oval holes: must also have the same orientation
1073  if( pad->GetOrientation() == aRefPad->GetOrientation() )
1074  continue;
1075  }
1076 
1077  /* Here, we must test clearance between holes and pads
1078  * dummy pad size and shape is adjusted to pad drill size and shape
1079  */
1080  if( pad->GetDrillSize().x )
1081  {
1082  // pad under testing has a hole, test this hole against pad reference
1083  dummypad.SetPosition( pad->GetPosition() );
1084  dummypad.SetSize( pad->GetDrillSize() );
1085  dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
1087  dummypad.SetOrientation( pad->GetOrientation() );
1088 
1089  if( !checkClearancePadToPad( aRefPad, &dummypad ) )
1090  {
1091  // here we have a drc error on pad!
1092  m_currentMarker = fillMarker( pad, aRefPad,
1094  return false;
1095  }
1096  }
1097 
1098  if( aRefPad->GetDrillSize().x ) // pad reference has a hole
1099  {
1100  dummypad.SetPosition( aRefPad->GetPosition() );
1101  dummypad.SetSize( aRefPad->GetDrillSize() );
1102  dummypad.SetShape( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
1104  dummypad.SetOrientation( aRefPad->GetOrientation() );
1105 
1106  if( !checkClearancePadToPad( pad, &dummypad ) )
1107  {
1108  // here we have a drc error on aRefPad!
1109  m_currentMarker = fillMarker( aRefPad, pad,
1111  return false;
1112  }
1113  }
1114 
1115  continue;
1116  }
1117 
1118  // The pad must be in a net (i.e pt_pad->GetNet() != 0 ),
1119  // But no problem if pads have the same netcode (same net)
1120  if( pad->GetNetCode() && ( aRefPad->GetNetCode() == pad->GetNetCode() ) )
1121  continue;
1122 
1123  // if pads are from the same footprint
1124  if( pad->GetParent() == aRefPad->GetParent() )
1125  {
1126  // and have the same pad number ( equivalent pads )
1127 
1128  // one can argue that this 2nd test is not necessary, that any
1129  // two pads from a single module are acceptable. This 2nd test
1130  // should eventually be a configuration option.
1131  if( pad->PadNameEqual( aRefPad ) )
1132  continue;
1133  }
1134 
1135  // if either pad has no drill and is only on technical layers, not a clearance violation
1136  if( ( ( pad->GetLayerSet() & layerMask ) == 0 && !pad->GetDrillSize().x ) ||
1137  ( ( aRefPad->GetLayerSet() & layerMask ) == 0 && !aRefPad->GetDrillSize().x ) )
1138  {
1139  continue;
1140  }
1141 
1142  if( !checkClearancePadToPad( aRefPad, pad ) )
1143  {
1144  // here we have a drc error!
1146  return false;
1147  }
1148  }
1149 
1150  return true;
1151 }
1152 
1153 
1155 {
1156  // Detects missing (or malformed) footprint courtyard,
1157  // and for footprint with courtyard, courtyards overlap.
1158  wxString msg;
1159  bool success = true;
1160 
1161  // Update courtyard polygons, and test for missing courtyard definition:
1162  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1163  {
1164  bool is_ok = footprint->BuildPolyCourtyard();
1165 
1166  if( !is_ok && m_doFootprintOverlapping )
1167  {
1168  msg.Printf( _( "footprint \"%s\" has malformed courtyard" ),
1169  footprint->GetReference().GetData() );
1170  m_currentMarker = fillMarker( footprint->GetPosition(),
1172  msg, m_currentMarker );
1174  m_currentMarker = nullptr;
1175  success = false;
1176  }
1177 
1178  if( !m_doNoCourtyardDefined )
1179  continue;
1180 
1181  if( footprint->GetPolyCourtyardFront().OutlineCount() == 0 &&
1182  footprint->GetPolyCourtyardBack().OutlineCount() == 0 &&
1183  is_ok )
1184  {
1185  msg.Printf( _( "footprint \"%s\" has no courtyard defined" ),
1186  footprint->GetReference().GetData() );
1187  m_currentMarker = fillMarker( footprint->GetPosition(),
1189  msg, m_currentMarker );
1191  m_currentMarker = nullptr;
1192  success = false;
1193  }
1194  }
1195 
1197  return success;
1198 
1199  // Now test for overlapping on top layer:
1200  SHAPE_POLY_SET courtyard; // temporary storage of the courtyard of current footprint
1201 
1202  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1203  {
1204  if( footprint->GetPolyCourtyardFront().OutlineCount() == 0 )
1205  continue; // No courtyard defined
1206 
1207  for( MODULE* candidate = footprint->Next(); candidate; candidate = candidate->Next() )
1208  {
1209  if( candidate->GetPolyCourtyardFront().OutlineCount() == 0 )
1210  continue; // No courtyard defined
1211 
1212  courtyard.RemoveAllContours();
1213  courtyard.Append( footprint->GetPolyCourtyardFront() );
1214 
1215  // Build the common area between footprint and the candidate:
1216  courtyard.BooleanIntersection( candidate->GetPolyCourtyardFront(),
1218 
1219  // If no overlap, courtyard is empty (no common area).
1220  // Therefore if a common polygon exists, this is a DRC error
1221  if( courtyard.OutlineCount() )
1222  {
1223  //Overlap between footprint and candidate
1224  msg.Printf( _( "footprints \"%s\" and \"%s\" overlap on front (top) layer" ),
1225  footprint->GetReference().GetData(),
1226  candidate->GetReference().GetData() );
1227  VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 );
1228  wxPoint loc( pos.x, pos.y );
1230  m_currentMarker );
1232  m_currentMarker = nullptr;
1233  success = false;
1234  }
1235  }
1236  }
1237 
1238  // Test for overlapping on bottom layer:
1239  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1240  {
1241  if( footprint->GetPolyCourtyardBack().OutlineCount() == 0 )
1242  continue; // No courtyard defined
1243 
1244  for( MODULE* candidate = footprint->Next(); candidate; candidate = candidate->Next() )
1245  {
1246  if( candidate->GetPolyCourtyardBack().OutlineCount() == 0 )
1247  continue; // No courtyard defined
1248 
1249  courtyard.RemoveAllContours();
1250  courtyard.Append( footprint->GetPolyCourtyardBack() );
1251 
1252  // Build the common area between footprint and the candidate:
1253  courtyard.BooleanIntersection( candidate->GetPolyCourtyardBack(),
1255 
1256  // If no overlap, courtyard is empty (no common area).
1257  // Therefore if a common polygon exists, this is a DRC error
1258  if( courtyard.OutlineCount() )
1259  {
1260  //Overlap between footprint and candidate
1261  msg.Printf( _( "footprints \"%s\" and \"%s\" overlap on back (bottom) layer" ),
1262  footprint->GetReference().GetData(),
1263  candidate->GetReference().GetData() );
1264  VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 );
1265  wxPoint loc( pos.x, pos.y );
1267  m_currentMarker );
1269  m_currentMarker = nullptr;
1270  success = false;
1271  }
1272  }
1273  }
1274 
1275  return success;
1276 }
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:511
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:106
bool PadNameEqual(const D_PAD *other) const
Definition: class_pad.h:207
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc.h:211
void UpdateDisplayedCounts()
Definition: dialog_drc.cpp:753
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)
Definition: drc.cpp:187
int m_ycliplo
Definition: drc.h:205
#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:793
void GetRptSettings(bool *aEnable, wxString &aFileName)
Definition: dialog_drc.cpp:188
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:207
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:199
#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:487
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:190
#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.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void testTexts()
Definition: drc.cpp:847
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:971
BOARD * m_pcb
Definition: drc.h:210
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:755
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:832
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:593
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:122
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:496
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:532
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:1011
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:1020
int m_xcliphi
Definition: drc.h:206
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:209
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:626
#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:1154
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:191
TOOL_MANAGER * GetToolManager() const
Function GetToolManager returns the tool manager instance, if any.
Definition: draw_frame.h:902
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:603
void testTracks(wxWindow *aActiveWindow, bool aShowProgressBar)
Perform the DRC on all tracks.
Definition: drc.cpp:666
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:982
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:245
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
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.
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:163
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: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
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:213
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:644
const wxPoint GetPosition() const override
Definition: class_pad.h:220
~DRC()
Definition: drc.cpp:155
void testUnconnected()
Definition: drc.cpp:725
void RunTests(wxTextCtrl *aMessages=NULL)
Run all the tests specified with a previous call to SetSettings()
Definition: drc.cpp:363
int m_xcliplo
Definition: drc.h:204
#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:290
bool m_doUnconnectedTest
Definition: drc.h:170
double m_segmAngle
Definition: drc.h:198
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:179
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