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