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