KiCad PCB EDA Suite
DRC Class Reference

Class DRC is the Design Rule Checker, and performs all the DRC tests. More...

#include <drc_stuff.h>

Public Member Functions

 DRC (PCB_EDIT_FRAME *aPcbWindow)
 
 ~DRC ()
 
int Drc (TRACK *aRefSeg, TRACK *aList)
 Function Drc tests the current segment and returns the result and displays the error in the status panel only if one exists. More...
 
int Drc (ZONE_CONTAINER *aArea, int aCornerIndex)
 Function Drc tests the outline segment starting at CornerIndex and returns the result and displays the error in the status panel only if one exists. More...
 
int DrcBlind (TRACK *aRefSeg, TRACK *aList)
 Function DrcBlind tests the current segment and returns the result. More...
 
int TestZoneToZoneOutline (ZONE_CONTAINER *aZone, bool aCreateMarkers)
 
void ShowDRCDialog (wxWindow *aParent=NULL)
 Function ShowDRCDialog opens a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and creates the MARKERS. More...
 
void DestroyDRCDialog (int aReason)
 Function DestroyDRCDialog deletes this ui dialog box and zeros out its pointer to remember the state of the dialog's existence. More...
 
void SetSettings (bool aPad2PadTest, bool aUnconnectedTest, bool aZonesTest, bool aKeepoutTest, bool aCourtyardTest, bool aCourtyardMissingTest, const wxString &aReportName, bool aSaveReport)
 Function SetSettings saves all the UI or test settings and may be called before running the tests. More...
 
void RunTests (wxTextCtrl *aMessages=NULL)
 Function RunTests will actually run all the tests specified with a previous call to SetSettings() More...
 
void ListUnconnectedPads ()
 Function ListUnconnectedPad gathers a list of all the unconnected pads and shows them in the dialog, and optionally prints a report of such. More...
 
MARKER_PCBGetCurrentMarker ()
 

Private Member Functions

void updatePointers ()
 Function updatePointers is a private helper function used to update needed pointers from the one pointer which is known not to change, m_pcbEditorFrame. More...
 
MARKER_PCBfillMarker (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 to the BOARD. More...
 
MARKER_PCBfillMarker (D_PAD *aPad, BOARD_ITEM *aItem, int aErrorCode, MARKER_PCB *fillMe)
 
MARKER_PCBfillMarker (ZONE_CONTAINER *aArea, int aErrorCode, MARKER_PCB *fillMe)
 
MARKER_PCBfillMarker (const wxPoint &aPos, int aErrorCode, const wxString &aMessage, MARKER_PCB *fillMe)
 
MARKER_PCBfillMarker (const ZONE_CONTAINER *aArea, const wxPoint &aPos, int aErrorCode, MARKER_PCB *fillMe)
 Function fillMarker optionally creates a marker and fills it in with information, but does not add it to the BOARD. More...
 
MARKER_PCBfillMarker (int aErrorCode, const wxString &aMessage, MARKER_PCB *fillMe)
 Function fillMarker fills a MARKER which will report on a generic problem with the board which is not geographically locatable. More...
 
void addMarkerToPcb (MARKER_PCB *aMarker)
 Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism. More...
 
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. More...
 
void testTracks (wxWindow *aActiveWindow, bool aShowProgressBar)
 Function testTracks performs the DRC on all tracks. More...
 
void testPad2Pad ()
 
void testUnconnected ()
 
void testZones ()
 
void testKeepoutAreas ()
 
void testTexts ()
 
bool doNetClass (const std::shared_ptr< NETCLASS > &aNetClass, wxString &msg)
 
bool doPadToPadsDrc (D_PAD *aRefPad, D_PAD **aStart, D_PAD **aEnd, int x_limit)
 Function doPadToPadsDrc tests the clearance between aRefPad and other pads. More...
 
bool doTrackDrc (TRACK *aRefSeg, TRACK *aStart, bool doPads=true)
 Function DoTrackDrc tests the current segment. More...
 
bool doTrackKeepoutDrc (TRACK *aRefSeg)
 Function doTrackKeepoutDrc tests the current segment or via. More...
 
bool doEdgeZoneDrc (ZONE_CONTAINER *aArea, int aCornerIndex)
 Function doEdgeZoneDrc tests a segment in ZONE_CONTAINER * aArea: Test Edge inside other areas Test Edge too close other areas. More...
 
bool doFootprintOverlappingDrc ()
 Function doFootprintOverlappingDrc tests for footprint courtyard overlaps. More...
 
bool checkClearancePadToPad (D_PAD *aRefPad, D_PAD *aPad)
 Function checkClearancePadToPad. More...
 
bool checkClearanceSegmToPad (const D_PAD *aPad, int aSegmentWidth, int aMinDist)
 Function checkClearanceSegmToPad check the distance from a pad to segment. More...
 
bool checkLine (wxPoint aSegStart, wxPoint aSegEnd)
 Function checkLine (helper function used in drc calculations to see if one track is in contact with another track). More...
 

Static Private Member Functions

static bool checkMarginToCircle (wxPoint aCentre, int aRadius, int aLength)
 Helper function checkMarginToCircle Check the distance from a point to a segment. More...
 

Private Attributes

bool m_doPad2PadTest
 
bool m_doUnconnectedTest
 
bool m_doZonesTest
 
bool m_doKeepoutTest
 
bool m_doCreateRptFile
 
bool m_doFootprintOverlapping
 
bool m_doNoCourtyardDefined
 
wxString m_rptFilename
 
MARKER_PCBm_currentMarker
 
bool m_abortDRC
 
bool m_drcInProgress
 
wxPoint m_padToTestPos
 
wxPoint m_segmEnd
 
double m_segmAngle
 
int m_segmLength
 
int m_xcliplo
 
int m_ycliplo
 
int m_xcliphi
 
int m_ycliphi
 
PCB_EDIT_FRAMEm_pcbEditorFrame
 The pcb frame editor which owns the board. More...
 
BOARDm_pcb
 
DIALOG_DRC_CONTROLm_drcDialog
 
DRC_LIST m_unconnected
 list of unconnected pads, as DRC_ITEMs More...
 

Friends

class DIALOG_DRC_CONTROL
 

Detailed Description

Class DRC is the Design Rule Checker, and performs all the DRC tests.

The output of the checking goes to the BOARD file in the form of two MARKER lists. Those two lists are displayable in the drc dialog box. And they can optionally be sent to a text file on disk. This class is given access to the windows and the BOARD that it needs via its constructor or public access functions.

Definition at line 164 of file drc_stuff.h.

Constructor & Destructor Documentation

DRC::DRC ( PCB_EDIT_FRAME aPcbWindow)

Definition at line 118 of file drc.cpp.

References PCB_BASE_FRAME::GetBoard(), m_abortDRC, m_currentMarker, m_doCreateRptFile, m_doFootprintOverlapping, m_doKeepoutTest, m_doNoCourtyardDefined, m_doPad2PadTest, m_doUnconnectedTest, m_doZonesTest, m_drcDialog, m_drcInProgress, m_pcb, m_pcbEditorFrame, m_segmAngle, m_segmLength, m_xcliphi, m_xcliplo, m_ycliphi, and m_ycliplo.

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 }
bool m_doNoCourtyardDefined
Definition: drc_stuff.h:178
bool m_doCreateRptFile
Definition: drc_stuff.h:176
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc_stuff.h:212
int m_ycliplo
Definition: drc_stuff.h:206
int m_ycliphi
Definition: drc_stuff.h:208
int m_segmLength
Definition: drc_stuff.h:200
BOARD * GetBoard() const
BOARD * m_pcb
Definition: drc_stuff.h:211
bool m_doFootprintOverlapping
Definition: drc_stuff.h:177
bool m_doKeepoutTest
Definition: drc_stuff.h:175
bool m_doZonesTest
Definition: drc_stuff.h:174
bool m_abortDRC
Definition: drc_stuff.h:184
bool m_drcInProgress
Definition: drc_stuff.h:185
int m_xcliphi
Definition: drc_stuff.h:207
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc_stuff.h:210
bool m_doPad2PadTest
Definition: drc_stuff.h:172
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
int m_xcliplo
Definition: drc_stuff.h:205
bool m_doUnconnectedTest
Definition: drc_stuff.h:173
double m_segmAngle
Definition: drc_stuff.h:199
DRC::~DRC ( )

Definition at line 150 of file drc.cpp.

References m_unconnected.

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 }
DRC_LIST m_unconnected
list of unconnected pads, as DRC_ITEMs
Definition: drc_stuff.h:214

Member Function Documentation

void DRC::addMarkerToPcb ( MARKER_PCB aMarker)
private

Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism.

Definition at line 94 of file drc.cpp.

References COMMIT::Add(), m_pcbEditorFrame, and BOARD_COMMIT::Push().

Referenced by doFootprintOverlappingDrc(), doNetClass(), testKeepoutAreas(), testPad2Pad(), testTexts(), testTracks(), and testZones().

95 {
97  commit.Add( aMarker );
98  commit.Push( wxEmptyString, false );
99 }
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc_stuff.h:210
bool DRC::checkClearancePadToPad ( D_PAD aRefPad,
D_PAD aPad 
)
private

Function checkClearancePadToPad.

Parameters
aRefPadThe reference pad to check
aPadAnother pad to check against
Returns
bool - true if clearance between aRefPad and aPad is >= dist_min, else false

Definition at line 709 of file drc_clearance_test_functions.cpp.

References SHAPE_POLY_SET::Append(), ArcTangente(), D_PAD::BuildPadPolygon(), checkClearanceSegmToPad(), SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), D_PAD::CustomShapeAsPolygonToBoardPosition(), delta, dist, EuclideanNorm(), D_PAD::GetBoundingRadius(), D_PAD::GetClearance(), D_PAD::GetCustomShapeAsPolygon(), D_PAD::GetOrientation(), GetRoundRectCornerCenters(), D_PAD::GetRoundRectCornerRadius(), D_PAD::GetShape(), D_PAD::GetSize(), KiROUND(), m_padToTestPos, m_segmAngle, m_segmEnd, m_segmLength, NORMALIZE_ANGLE_POS(), SHAPE_POLY_SET::OutlineCount(), PAD_SHAPE_CIRCLE, PAD_SHAPE_CUSTOM, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, SHAPE_LINE_CHAIN::PointCount(), poly2polyDRC(), RotatePoint(), D_PAD::ShapePos(), wxPoint::x, and wxPoint::y.

Referenced by doPadToPadsDrc().

710 {
711  int dist;
712  double pad_angle;
713 
714  // Get the clearance between the 2 pads. this is the min distance between aRefPad and aPad
715  int dist_min = aRefPad->GetClearance( aPad );
716 
717  // relativePadPos is the aPad shape position relative to the aRefPad shape position
718  wxPoint relativePadPos = aPad->ShapePos() - aRefPad->ShapePos();
719 
720  dist = KiROUND( EuclideanNorm( relativePadPos ) );
721 
722  // Quick test: Clearance is OK if the bounding circles are further away than "dist_min"
723  int delta = dist - aRefPad->GetBoundingRadius() - aPad->GetBoundingRadius();
724 
725  if( delta >= dist_min )
726  return true;
727 
728  /* Here, pads are near and DRC depend on the pad shapes
729  * We must compare distance using a fine shape analysis
730  * Because a circle or oval shape is the easier shape to test, try to have
731  * aRefPad shape type = PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL.
732  * if aRefPad = TRAP. and aPad = RECT, also swap pads
733  * Swap aRefPad and aPad if needed
734  */
735  bool swap_pads;
736  swap_pads = false;
737 
738  // swap pads to make comparisons easier
739  // Note also a ROUNDRECT pad with a corner radius = r can be considered as
740  // a smaller RECT (size - 2*r) with a clearance increased by r
741  // priority is aRefPad = ROUND then OVAL then RECT/ROUNDRECT then other
742  if( aRefPad->GetShape() != aPad->GetShape() && aRefPad->GetShape() != PAD_SHAPE_CIRCLE )
743  {
744  // pad ref shape is here oval, rect, roundrect, trapezoid or custom
745  switch( aPad->GetShape() )
746  {
747  case PAD_SHAPE_CIRCLE:
748  swap_pads = true;
749  break;
750 
751  case PAD_SHAPE_OVAL:
752  swap_pads = true;
753  break;
754 
755  case PAD_SHAPE_RECT:
756  case PAD_SHAPE_ROUNDRECT:
757  if( aRefPad->GetShape() != PAD_SHAPE_OVAL )
758  swap_pads = true;
759  break;
760 
761  case PAD_SHAPE_TRAPEZOID:
762  case PAD_SHAPE_CUSTOM:
763  break;
764  }
765  }
766 
767  if( swap_pads )
768  {
769  std::swap( aRefPad, aPad );
770  relativePadPos = -relativePadPos;
771  }
772 
773  // corners of aRefPad (used only for rect/roundrect/trap pad)
774  wxPoint polyref[4];
775  // corners of aRefPad (used only for custom pad)
776  SHAPE_POLY_SET polysetref;
777 
778  // corners of aPad (used only for rect/roundrect/trap pad)
779  wxPoint polycompare[4];
780  // corners of aPad (used only custom pad)
781  SHAPE_POLY_SET polysetcompare;
782 
783  /* Because pad exchange, aRefPad shape is PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL,
784  * if one of the 2 pads was a PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL.
785  * Therefore, if aRefPad is a PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT or a PAD_SHAPE_TRAPEZOID,
786  * aPad is also a PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT or a PAD_SHAPE_TRAPEZOID
787  */
788  bool diag = true;
789 
790  switch( aRefPad->GetShape() )
791  {
792  case PAD_SHAPE_CIRCLE:
793 
794  /* One can use checkClearanceSegmToPad to test clearance
795  * aRefPad is like a track segment with a null length and a witdth = GetSize().x
796  */
797  m_segmLength = 0;
798  m_segmAngle = 0;
799 
800  m_segmEnd.x = m_segmEnd.y = 0;
801 
802  m_padToTestPos = relativePadPos;
803  diag = checkClearanceSegmToPad( aPad, aRefPad->GetSize().x, dist_min );
804  break;
805 
806  case PAD_SHAPE_TRAPEZOID:
807  case PAD_SHAPE_ROUNDRECT:
808  case PAD_SHAPE_RECT:
809  case PAD_SHAPE_CUSTOM:
810  // pad_angle = pad orient relative to the aRefPad orient
811  pad_angle = aRefPad->GetOrientation() + aPad->GetOrientation();
812  NORMALIZE_ANGLE_POS( pad_angle );
813 
814  if( aRefPad->GetShape() == PAD_SHAPE_ROUNDRECT )
815  {
816  int padRadius = aRefPad->GetRoundRectCornerRadius();
817  dist_min += padRadius;
818  GetRoundRectCornerCenters( polyref, padRadius, wxPoint( 0, 0 ),
819  aRefPad->GetSize(), aRefPad->GetOrientation() );
820  }
821  else if( aRefPad->GetShape() == PAD_SHAPE_CUSTOM )
822  {
823  polysetref.Append( aRefPad->GetCustomShapeAsPolygon() );
824 
825  // The reference pad can be rotated. calculate the rotated
826  // coordiantes ( note, the ref pad position is the origin of
827  // coordinates for this drc test)
828  aRefPad->CustomShapeAsPolygonToBoardPosition( &polysetref,
829  wxPoint( 0, 0 ), aRefPad->GetOrientation() );
830  }
831  else
832  {
833  // BuildPadPolygon has meaning for rect a trapeziod shapes
834  // and returns the 4 corners
835  aRefPad->BuildPadPolygon( polyref, wxSize( 0, 0 ), aRefPad->GetOrientation() );
836  }
837 
838  switch( aPad->GetShape() )
839  {
840  case PAD_SHAPE_ROUNDRECT:
841  case PAD_SHAPE_RECT:
842  case PAD_SHAPE_TRAPEZOID:
843  case PAD_SHAPE_CUSTOM:
844  if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
845  {
846  int padRadius = aPad->GetRoundRectCornerRadius();
847  dist_min += padRadius;
848  GetRoundRectCornerCenters( polycompare, padRadius, relativePadPos,
849  aPad->GetSize(), aPad->GetOrientation() );
850  }
851  else if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
852  {
853  polysetcompare.Append( aPad->GetCustomShapeAsPolygon() );
854 
855  // The pad to compare can be rotated. calculate the rotated
856  // coordinattes ( note, the pad to compare position
857  // is the relativePadPos for this drc test
858  aPad->CustomShapeAsPolygonToBoardPosition( &polysetcompare,
859  relativePadPos, aPad->GetOrientation() );
860  }
861  else
862  {
863  aPad->BuildPadPolygon( polycompare, wxSize( 0, 0 ), aPad->GetOrientation() );
864 
865  // Move aPad shape to relativePadPos
866  for( int ii = 0; ii < 4; ii++ )
867  polycompare[ii] += relativePadPos;
868  }
869  // And now test polygons: We have 3 cases:
870  // one poly is complex and the other is basic (has only 4 corners)
871  // both polys are complex
872  // both polys are basic (have only 4 corners) the most usual case
873  if( polysetref.OutlineCount() && polysetcompare.OutlineCount() == 0)
874  {
875  const SHAPE_LINE_CHAIN& refpoly = polysetref.COutline( 0 );
876  // And now test polygons:
877  if( !poly2polyDRC( (wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
878  polycompare, 4, dist_min ) )
879  diag = false;
880  }
881  else if( polysetref.OutlineCount() == 0 && polysetcompare.OutlineCount())
882  {
883  const SHAPE_LINE_CHAIN& cmppoly = polysetcompare.COutline( 0 );
884  // And now test polygons:
885  if( !poly2polyDRC( (wxPoint*) &cmppoly.CPoint( 0 ), cmppoly.PointCount(),
886  polyref, 4, dist_min ) )
887  diag = false;
888  }
889  else if( polysetref.OutlineCount() && polysetcompare.OutlineCount() )
890  {
891  const SHAPE_LINE_CHAIN& refpoly = polysetref.COutline( 0 );
892  const SHAPE_LINE_CHAIN& cmppoly = polysetcompare.COutline( 0 );
893 
894  // And now test polygons:
895  if( !poly2polyDRC( (wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
896  (wxPoint*) &cmppoly.CPoint( 0 ), cmppoly.PointCount(), dist_min ) )
897  diag = false;
898  }
899  else if( !poly2polyDRC( polyref, 4, polycompare, 4, dist_min ) )
900  diag = false;
901  break;
902 
903  default:
904  wxLogDebug( wxT( "DRC::checkClearancePadToPad: unexpected pad shape %d" ), aPad->GetShape() );
905  break;
906  }
907  break;
908 
909  case PAD_SHAPE_OVAL: /* an oval pad is like a track segment */
910  {
911  /* Create a track segment with same dimensions as the oval aRefPad
912  * and use checkClearanceSegmToPad function to test aPad to aRefPad clearance
913  */
914  int segm_width;
915  m_segmAngle = aRefPad->GetOrientation(); // Segment orient.
916 
917  if( aRefPad->GetSize().y < aRefPad->GetSize().x ) // Build an horizontal equiv segment
918  {
919  segm_width = aRefPad->GetSize().y;
920  m_segmLength = aRefPad->GetSize().x - aRefPad->GetSize().y;
921  }
922  else // Vertical oval: build an horizontal equiv segment and rotate 90.0 deg
923  {
924  segm_width = aRefPad->GetSize().x;
925  m_segmLength = aRefPad->GetSize().y - aRefPad->GetSize().x;
926  m_segmAngle += 900;
927  }
928 
929  /* the start point must be 0,0 and currently relativePadPos
930  * is relative the center of pad coordinate */
931  wxPoint segstart;
932  segstart.x = -m_segmLength / 2; // Start point coordinate of the horizontal equivalent segment
933 
934  RotatePoint( &segstart, m_segmAngle ); // actual start point coordinate of the equivalent segment
935  // Calculate segment end position relative to the segment origin
936  m_segmEnd.x = -2 * segstart.x;
937  m_segmEnd.y = -2 * segstart.y;
938 
939  // Recalculate the equivalent segment angle in 0,1 degrees
940  // to prepare a call to checkClearanceSegmToPad()
942 
943  // move pad position relative to the segment origin
944  m_padToTestPos = relativePadPos - segstart;
945 
946  // Use segment to pad check to test the second pad:
947  diag = checkClearanceSegmToPad( aPad, segm_width, dist_min );
948  break;
949  }
950 
951  default:
952  wxMessageBox( wxT( "DRC::checkClearancePadToPad: unknown pad shape" ) );
953  break;
954  }
955 
956  return diag;
957 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
const SHAPE_POLY_SET & GetCustomShapeAsPolygon() const
Accessor to the custom shape as one polygon.
Definition: class_pad.h:341
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
int PointCount() const
Function PointCount()
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:511
static const int dist[10][10]
Definition: dist.cpp:57
int m_segmLength
Definition: drc_stuff.h:200
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
int OutlineCount() const
Returns the number of outlines in the set
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:241
wxPoint m_padToTestPos
Definition: drc_stuff.h:191
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
static const int delta[8][2]
Definition: solve.cpp:112
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0...
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:271
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:586
Class SHAPE_POLY_SET.
const wxSize & GetSize() const
Definition: class_pad.h:269
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
bool checkClearanceSegmToPad(const D_PAD *aPad, int aSegmentWidth, int aMinDist)
Function checkClearanceSegmToPad check the distance from a pad to segment.
wxPoint m_segmEnd
Definition: drc_stuff.h:192
Class SHAPE_LINE_CHAIN.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:375
bool poly2polyDRC(wxPoint *aTref, int aTrefCount, wxPoint *aTcompare, int aTcompareCount, int aDist)
DRC control: these functions make a DRC between pads, tracks and pads versus tracks.
void GetRoundRectCornerCenters(wxPoint aCenters[4], int aRadius, const wxPoint &aPosition, const wxSize &aSize, double aRotation)
Helper function GetRoundRectCornerCenters Has meaning only for rounded rect Returns the centers of th...
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_pad.cpp:546
wxPoint ShapePos() const
Definition: class_pad.cpp:500
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
double m_segmAngle
Definition: drc_stuff.h:199
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) ...
bool DRC::checkClearanceSegmToPad ( const D_PAD aPad,
int  aSegmentWidth,
int  aMinDist 
)
private

Function checkClearanceSegmToPad check the distance from a pad to segment.

This function uses several instance variable not passed in: m_segmLength = length of the segment being tested m_segmAngle = angle of the segment with the X axis; m_segmEnd = end coordinate of the segment m_padToTestPos = position of pad relative to the origin of segment

Parameters
aPadIs the pad involved in the check
aSegmentWidthwidth of the segment to test
aMinDistIs the minimum clearance needed
Returns
true distance >= dist_min, false if distance < dist_min

Definition at line 965 of file drc_clearance_test_functions.cpp.

References abs, AddAngles(), SHAPE_POLY_SET::Append(), D_PAD::BuildPadPolygon(), checkLine(), checkMarginToCircle(), SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), D_PAD::CustomShapeAsPolygonToBoardPosition(), D_PAD::GetBoundingRadius(), D_PAD::GetCustomShapeAsPolygon(), D_PAD::GetDelta(), D_PAD::GetOrientation(), D_PAD::GetRoundRectCornerRadius(), D_PAD::GetShape(), D_PAD::GetSize(), m_padToTestPos, m_segmAngle, m_segmEnd, m_segmLength, m_xcliphi, m_xcliplo, m_ycliphi, m_ycliplo, PAD_SHAPE_CIRCLE, PAD_SHAPE_CUSTOM, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, SHAPE_LINE_CHAIN::PointCount(), poly2segmentDRC(), RotatePoint(), wxPoint::x, and wxPoint::y.

Referenced by checkClearancePadToPad(), doTrackDrc(), and testTexts().

966 {
967  // Note:
968  // we are using a horizontal segment for test, because we know here
969  // only the length and orientation+ of the segment
970  // Therefore the coordinates of the shape of pad to compare
971  // must be calculated in a axis system rotated by m_segmAngle
972  // and centered to the segment origin, before they can be tested
973  // against the segment
974  // We are using:
975  // m_padToTestPos the position of the pad shape in this axis system
976  // m_segmAngle the axis system rotation
977 
978  int segmHalfWidth = aSegmentWidth / 2;
979  int distToLine = segmHalfWidth + aMinDist;
980 
981  wxSize padHalfsize; // half dimension of the pad
982 
983  if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
984  {
985  // For a custom pad, the pad size has no meaning, we only can
986  // use the bounding radius
987  padHalfsize.x = padHalfsize.y = aPad->GetBoundingRadius();
988  }
989  else
990  {
991  padHalfsize.x = aPad->GetSize().x >> 1;
992  padHalfsize.y = aPad->GetSize().y >> 1;
993  }
994 
995  if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID ) // The size is bigger, due to GetDelta() extra size
996  {
997  padHalfsize.x += std::abs(aPad->GetDelta().y) / 2; // Remember: GetDelta().y is the GetSize().x change
998  padHalfsize.y += std::abs(aPad->GetDelta().x) / 2; // Remember: GetDelta().x is the GetSize().y change
999  }
1000 
1001  if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
1002  {
1003  /* Easy case: just test the distance between segment and pad centre
1004  * calculate pad coordinates in the X,Y axis with X axis = segment to test
1005  */
1007  return checkMarginToCircle( m_padToTestPos, distToLine + padHalfsize.x, m_segmLength );
1008  }
1009 
1010  /* calculate the bounding box of the pad, including the clearance and the segment width
1011  * if the line from 0 to m_segmEnd does not intersect this bounding box,
1012  * the clearance is always OK
1013  * But if intersect, a better analysis of the pad shape must be done.
1014  */
1015  m_xcliplo = m_padToTestPos.x - distToLine - padHalfsize.x;
1016  m_ycliplo = m_padToTestPos.y - distToLine - padHalfsize.y;
1017  m_xcliphi = m_padToTestPos.x + distToLine + padHalfsize.x;
1018  m_ycliphi = m_padToTestPos.y + distToLine + padHalfsize.y;
1019 
1020  wxPoint startPoint;
1021  wxPoint endPoint = m_segmEnd;
1022 
1023  double orient = aPad->GetOrientation();
1024 
1025  RotatePoint( &startPoint, m_padToTestPos, -orient );
1026  RotatePoint( &endPoint, m_padToTestPos, -orient );
1027 
1028  if( checkLine( startPoint, endPoint ) )
1029  return true;
1030 
1031  /* segment intersects the bounding box. But there is not always a DRC error.
1032  * A fine analysis of the pad shape must be done.
1033  */
1034  switch( aPad->GetShape() )
1035  {
1036  case PAD_SHAPE_CIRCLE:
1037  // This case was already tested, so it cannot be found here.
1038  // it is here just to avoid compil warning, and to remember
1039  // it is already tested.
1040  return false;
1041 
1042  case PAD_SHAPE_OVAL:
1043  {
1044  /* an oval is a complex shape, but is a rectangle and 2 circles
1045  * these 3 basic shapes are more easy to test.
1046  *
1047  * In calculations we are using a vertical oval shape
1048  * (i.e. a vertical rounded segment)
1049  * for horizontal oval shapes, swap x and y size and rotate the shape
1050  */
1051  if( padHalfsize.x > padHalfsize.y )
1052  {
1053  std::swap( padHalfsize.x, padHalfsize.y );
1054  orient = AddAngles( orient, 900 );
1055  }
1056 
1057  // here, padHalfsize.x is the radius of rounded ends.
1058 
1059  int deltay = padHalfsize.y - padHalfsize.x;
1060  // here: padHalfsize.x = radius,
1061  // deltay = dist between the centre pad and the centre of a rounded end
1062 
1063  // Test the rectangular area between the two circles (the rounded ends)
1064  m_xcliplo = m_padToTestPos.x - distToLine - padHalfsize.x;
1065  m_ycliplo = m_padToTestPos.y - deltay;
1066  m_xcliphi = m_padToTestPos.x + distToLine + padHalfsize.x;
1067  m_ycliphi = m_padToTestPos.y + deltay;
1068 
1069  if( !checkLine( startPoint, endPoint ) )
1070  {
1071  return false;
1072  }
1073 
1074  // test the first circle
1075  startPoint.x = m_padToTestPos.x; // startPoint = centre of the upper circle of the oval shape
1076  startPoint.y = m_padToTestPos.y + deltay;
1077 
1078  // Calculate the actual position of the circle, given the pad orientation:
1079  RotatePoint( &startPoint, m_padToTestPos, orient );
1080 
1081  // Calculate the actual position of the circle in the new X,Y axis:
1082  RotatePoint( &startPoint, m_segmAngle );
1083 
1084  if( !checkMarginToCircle( startPoint, padHalfsize.x + distToLine, m_segmLength ) )
1085  {
1086  return false;
1087  }
1088 
1089  // test the second circle
1090  startPoint.x = m_padToTestPos.x; // startPoint = centre of the lower circle of the oval shape
1091  startPoint.y = m_padToTestPos.y - deltay;
1092  RotatePoint( &startPoint, m_padToTestPos, orient );
1093  RotatePoint( &startPoint, m_segmAngle );
1094 
1095  if( !checkMarginToCircle( startPoint, padHalfsize.x + distToLine, m_segmLength ) )
1096  {
1097  return false;
1098  }
1099  }
1100  break;
1101 
1102  case PAD_SHAPE_ROUNDRECT:
1103  {
1104  // a round rect is a smaller rect, with a clearance augmented by the corners radius
1105  int r = aPad->GetRoundRectCornerRadius();
1106  padHalfsize.x -= r;
1107  padHalfsize.y -= r;
1108  distToLine += r;
1109  }
1110  // Fall through
1111  case PAD_SHAPE_RECT:
1112  // the area to test is a rounded rectangle.
1113  // this can be done by testing 2 rectangles and 4 circles (the corners)
1114 
1115  // Testing the first rectangle dimx + distToLine, dimy:
1116  m_xcliplo = m_padToTestPos.x - padHalfsize.x - distToLine;
1117  m_ycliplo = m_padToTestPos.y - padHalfsize.y;
1118  m_xcliphi = m_padToTestPos.x + padHalfsize.x + distToLine;
1119  m_ycliphi = m_padToTestPos.y + padHalfsize.y;
1120 
1121  if( !checkLine( startPoint, endPoint ) )
1122  return false;
1123 
1124  // Testing the second rectangle dimx , dimy + distToLine
1125  m_xcliplo = m_padToTestPos.x - padHalfsize.x;
1126  m_ycliplo = m_padToTestPos.y - padHalfsize.y - distToLine;
1127  m_xcliphi = m_padToTestPos.x + padHalfsize.x;
1128  m_ycliphi = m_padToTestPos.y + padHalfsize.y + distToLine;
1129 
1130  if( !checkLine( startPoint, endPoint ) )
1131  return false;
1132 
1133  // testing the 4 circles which are the clearance area of each corner:
1134 
1135  // testing the left top corner of the rectangle
1136  startPoint.x = m_padToTestPos.x - padHalfsize.x;
1137  startPoint.y = m_padToTestPos.y - padHalfsize.y;
1138  RotatePoint( &startPoint, m_padToTestPos, orient );
1139  RotatePoint( &startPoint, m_segmAngle );
1140 
1141  if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
1142  return false;
1143 
1144  // testing the right top corner of the rectangle
1145  startPoint.x = m_padToTestPos.x + padHalfsize.x;
1146  startPoint.y = m_padToTestPos.y - padHalfsize.y;
1147  RotatePoint( &startPoint, m_padToTestPos, orient );
1148  RotatePoint( &startPoint, m_segmAngle );
1149 
1150  if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
1151  return false;
1152 
1153  // testing the left bottom corner of the rectangle
1154  startPoint.x = m_padToTestPos.x - padHalfsize.x;
1155  startPoint.y = m_padToTestPos.y + padHalfsize.y;
1156  RotatePoint( &startPoint, m_padToTestPos, orient );
1157  RotatePoint( &startPoint, m_segmAngle );
1158 
1159  if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
1160  return false;
1161 
1162  // testing the right bottom corner of the rectangle
1163  startPoint.x = m_padToTestPos.x + padHalfsize.x;
1164  startPoint.y = m_padToTestPos.y + padHalfsize.y;
1165  RotatePoint( &startPoint, m_padToTestPos, orient );
1166  RotatePoint( &startPoint, m_segmAngle );
1167 
1168  if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
1169  return false;
1170 
1171  break;
1172 
1173  case PAD_SHAPE_TRAPEZOID:
1174  {
1175  wxPoint poly[4];
1176  aPad->BuildPadPolygon( poly, wxSize( 0, 0 ), orient );
1177 
1178  // Move shape to m_padToTestPos
1179  for( int ii = 0; ii < 4; ii++ )
1180  {
1181  poly[ii] += m_padToTestPos;
1182  RotatePoint( &poly[ii], m_segmAngle );
1183  }
1184 
1185  if( !poly2segmentDRC( poly, 4, wxPoint( 0, 0 ),
1186  wxPoint(m_segmLength,0), distToLine ) )
1187  return false;
1188  }
1189  break;
1190 
1191  case PAD_SHAPE_CUSTOM:
1192  {
1193  SHAPE_POLY_SET polyset;
1194  polyset.Append( aPad->GetCustomShapeAsPolygon() );
1195  // The pad can be rotated. calculate the coordinates
1196  // relatives to the segment being tested
1197  // Note, the pad position relative to the segment origin
1198  // is m_padToTestPos
1199  aPad->CustomShapeAsPolygonToBoardPosition( &polyset,
1200  m_padToTestPos, orient );
1201 
1202  // Rotate all coordinates by m_segmAngle, because the segment orient
1203  // is m_segmAngle
1204  // we are using a horizontal segment for test, because we know here
1205  // only the lenght and orientation+ of the segment
1206  // therefore all coordinates of the pad to test must be rotated by
1207  // m_segmAngle (they are already relative to the segment origin)
1208  aPad->CustomShapeAsPolygonToBoardPosition( &polyset,
1209  wxPoint( 0, 0 ), m_segmAngle );
1210 
1211  const SHAPE_LINE_CHAIN& refpoly = polyset.COutline( 0 );
1212 
1213  if( !poly2segmentDRC( (wxPoint*) &refpoly.CPoint( 0 ),
1214  refpoly.PointCount(),
1215  wxPoint( 0, 0 ), wxPoint(m_segmLength,0),
1216  distToLine ) )
1217  return false;
1218  }
1219  break;
1220  }
1221 
1222  return true;
1223 }
int m_ycliplo
Definition: drc_stuff.h:206
const SHAPE_POLY_SET & GetCustomShapeAsPolygon() const
Accessor to the custom shape as one polygon.
Definition: class_pad.h:341
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
int PointCount() const
Function PointCount()
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:511
int m_ycliphi
Definition: drc_stuff.h:208
bool poly2segmentDRC(wxPoint *aTref, int aTrefCount, wxPoint aSegStart, wxPoint aSegEnd, int aDist)
int m_segmLength
Definition: drc_stuff.h:200
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
wxPoint m_padToTestPos
Definition: drc_stuff.h:191
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:216
#define abs(a)
Definition: auxiliary.h:84
bool checkLine(wxPoint aSegStart, wxPoint aSegEnd)
Function checkLine (helper function used in drc calculations to see if one track is in contact with a...
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0...
T AddAngles(T a1, T2 a2)
Add two angles (keeping the result normalized). T2 is here.
Definition: trigo.h:267
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:586
Class SHAPE_POLY_SET.
const wxSize & GetSize() const
Definition: class_pad.h:269
static bool checkMarginToCircle(wxPoint aCentre, int aRadius, int aLength)
Helper function checkMarginToCircle Check the distance from a point to a segment. ...
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
int m_xcliphi
Definition: drc_stuff.h:207
wxPoint m_segmEnd
Definition: drc_stuff.h:192
Class SHAPE_LINE_CHAIN.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:375
const wxSize & GetDelta() const
Definition: class_pad.h:272
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
int m_xcliplo
Definition: drc_stuff.h:205
double m_segmAngle
Definition: drc_stuff.h:199
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) ...
bool DRC::checkLine ( wxPoint  aSegStart,
wxPoint  aSegEnd 
)
private

Function checkLine (helper function used in drc calculations to see if one track is in contact with another track).

Helper function checkLine Test if a line intersects a bounding box (a rectangle) The rectangle is defined by m_xcliplo, m_ycliplo and m_xcliphi, m_ycliphi return true if the line from aSegStart to aSegEnd is outside the bounding box.

Test if a line intersects a bounding box (a rectangle) The rectangle is defined by m_xcliplo, m_ycliplo and m_xcliphi, m_ycliphi return true if the line from aSegStart to aSegEnd is outside the bounding box

Definition at line 1270 of file drc_clearance_test_functions.cpp.

References m_xcliphi, m_xcliplo, m_ycliphi, m_ycliplo, USCALE(), WHEN_INSIDE, WHEN_OUTSIDE, wxPoint::x, and wxPoint::y.

Referenced by checkClearanceSegmToPad(), and doTrackDrc().

1271 {
1272 #define WHEN_OUTSIDE return true
1273 #define WHEN_INSIDE
1274  int temp;
1275 
1276  if( aSegStart.x > aSegEnd.x )
1277  std::swap( aSegStart, aSegEnd );
1278 
1279  if( (aSegEnd.x < m_xcliplo) || (aSegStart.x > m_xcliphi) )
1280  {
1281  WHEN_OUTSIDE;
1282  }
1283 
1284  if( aSegStart.y < aSegEnd.y )
1285  {
1286  if( (aSegEnd.y < m_ycliplo) || (aSegStart.y > m_ycliphi) )
1287  {
1288  WHEN_OUTSIDE;
1289  }
1290 
1291  if( aSegStart.y < m_ycliplo )
1292  {
1293  temp = USCALE( (aSegEnd.x - aSegStart.x), (m_ycliplo - aSegStart.y),
1294  (aSegEnd.y - aSegStart.y) );
1295 
1296  if( (aSegStart.x += temp) > m_xcliphi )
1297  {
1298  WHEN_OUTSIDE;
1299  }
1300 
1301  aSegStart.y = m_ycliplo;
1302  WHEN_INSIDE;
1303  }
1304 
1305  if( aSegEnd.y > m_ycliphi )
1306  {
1307  temp = USCALE( (aSegEnd.x - aSegStart.x), (aSegEnd.y - m_ycliphi),
1308  (aSegEnd.y - aSegStart.y) );
1309 
1310  if( (aSegEnd.x -= temp) < m_xcliplo )
1311  {
1312  WHEN_OUTSIDE;
1313  }
1314 
1315  aSegEnd.y = m_ycliphi;
1316  WHEN_INSIDE;
1317  }
1318 
1319  if( aSegStart.x < m_xcliplo )
1320  {
1321  temp = USCALE( (aSegEnd.y - aSegStart.y), (m_xcliplo - aSegStart.x),
1322  (aSegEnd.x - aSegStart.x) );
1323  aSegStart.y += temp;
1324  aSegStart.x = m_xcliplo;
1325  WHEN_INSIDE;
1326  }
1327 
1328  if( aSegEnd.x > m_xcliphi )
1329  {
1330  temp = USCALE( (aSegEnd.y - aSegStart.y), (aSegEnd.x - m_xcliphi),
1331  (aSegEnd.x - aSegStart.x) );
1332  aSegEnd.y -= temp;
1333  aSegEnd.x = m_xcliphi;
1334  WHEN_INSIDE;
1335  }
1336  }
1337  else
1338  {
1339  if( (aSegStart.y < m_ycliplo) || (aSegEnd.y > m_ycliphi) )
1340  {
1341  WHEN_OUTSIDE;
1342  }
1343 
1344  if( aSegStart.y > m_ycliphi )
1345  {
1346  temp = USCALE( (aSegEnd.x - aSegStart.x), (aSegStart.y - m_ycliphi),
1347  (aSegStart.y - aSegEnd.y) );
1348 
1349  if( (aSegStart.x += temp) > m_xcliphi )
1350  {
1351  WHEN_OUTSIDE;
1352  }
1353 
1354  aSegStart.y = m_ycliphi;
1355  WHEN_INSIDE;
1356  }
1357 
1358  if( aSegEnd.y < m_ycliplo )
1359  {
1360  temp = USCALE( (aSegEnd.x - aSegStart.x), (m_ycliplo - aSegEnd.y),
1361  (aSegStart.y - aSegEnd.y) );
1362 
1363  if( (aSegEnd.x -= temp) < m_xcliplo )
1364  {
1365  WHEN_OUTSIDE;
1366  }
1367 
1368  aSegEnd.y = m_ycliplo;
1369  WHEN_INSIDE;
1370  }
1371 
1372  if( aSegStart.x < m_xcliplo )
1373  {
1374  temp = USCALE( (aSegStart.y - aSegEnd.y), (m_xcliplo - aSegStart.x),
1375  (aSegEnd.x - aSegStart.x) );
1376  aSegStart.y -= temp;
1377  aSegStart.x = m_xcliplo;
1378  WHEN_INSIDE;
1379  }
1380 
1381  if( aSegEnd.x > m_xcliphi )
1382  {
1383  temp = USCALE( (aSegStart.y - aSegEnd.y), (aSegEnd.x - m_xcliphi),
1384  (aSegEnd.x - aSegStart.x) );
1385  aSegEnd.y += temp;
1386  aSegEnd.x = m_xcliphi;
1387  WHEN_INSIDE;
1388  }
1389  }
1390 
1391  if( ( (aSegEnd.x + aSegStart.x) / 2 <= m_xcliphi )
1392  && ( (aSegEnd.x + aSegStart.x) / 2 >= m_xcliplo ) \
1393  && ( (aSegEnd.y + aSegStart.y) / 2 <= m_ycliphi )
1394  && ( (aSegEnd.y + aSegStart.y) / 2 >= m_ycliplo ) )
1395  {
1396  return false;
1397  }
1398  else
1399  {
1400  return true;
1401  }
1402 }
static int USCALE(unsigned arg, unsigned num, unsigned den)
#define WHEN_OUTSIDE
int m_ycliplo
Definition: drc_stuff.h:206
int m_ycliphi
Definition: drc_stuff.h:208
int m_xcliphi
Definition: drc_stuff.h:207
#define WHEN_INSIDE
int m_xcliplo
Definition: drc_stuff.h:205
bool DRC::checkMarginToCircle ( wxPoint  aCentre,
int  aRadius,
int  aLength 
)
staticprivate

Helper function checkMarginToCircle Check the distance from a point to a segment.

Helper function checkMarginToCircle Check the distance between a circle (round pad, via or round end of track) and a segment.

The segment is expected starting at 0,0, and on the X axis (used to test DRC between a segment and a round pad, via or round end of a track

Parameters
aCentreThe coordinate of the circle's center
aRadiusA "keep out" radius centered over the circle
aLengthThe length of the segment (i.e. coordinate of end, because it is on the X axis)
Returns
bool - true if distance >= radius, else false when distance < aRadius

the segment is expected starting at 0,0, and on the X axis return true if distance >= aRadius

Definition at line 1232 of file drc_clearance_test_functions.cpp.

References abs, EuclideanNorm(), wxPoint::x, and wxPoint::y.

Referenced by checkClearanceSegmToPad(), and doTrackDrc().

1233 {
1234  if( abs( aCentre.y ) >= aRadius ) // trivial case
1235  return true;
1236 
1237  // Here, distance between aCentre and X axis is < aRadius
1238  if( (aCentre.x > -aRadius ) && ( aCentre.x < (aLength + aRadius) ) )
1239  {
1240  if( (aCentre.x >= 0) && (aCentre.x <= aLength) )
1241  return false; // aCentre is between the starting point and the ending point of the segm
1242 
1243  if( aCentre.x > aLength ) // aCentre is after the ending point
1244  aCentre.x -= aLength; // move aCentre to the starting point of the segment
1245 
1246  if( EuclideanNorm( aCentre ) < aRadius )
1247  // distance between aCentre and the starting point or the ending point is < aRadius
1248  return false;
1249  }
1250 
1251  return true;
1252 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
#define abs(a)
Definition: auxiliary.h:84
void DRC::DestroyDRCDialog ( int  aReason)

Function DestroyDRCDialog deletes this ui dialog box and zeros out its pointer to remember the state of the dialog's existence.

Parameters
aReasonIndication of which button was clicked to cause the destruction. if aReason == wxID_OK, design parameters values which can be entered from the dialog will bbe saved in design parameters list

Definition at line 102 of file drc.cpp.

References DIALOG_DRC_CONTROL::GetRptSettings(), m_doCreateRptFile, m_drcDialog, and m_rptFilename.

Referenced by DIALOG_DRC_CONTROL::OnActivateDlg(), DIALOG_DRC_CONTROL::OnCancelClick(), DIALOG_DRC_CONTROL::OnOkClick(), and DIALOG_PLOT::onRunDRC().

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 }
bool m_doCreateRptFile
Definition: drc_stuff.h:176
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc_stuff.h:212
void GetRptSettings(bool *aEnable, wxString &aFileName)
Definition: dialog_drc.cpp:182
wxString m_rptFilename
Definition: drc_stuff.h:180
bool DRC::doEdgeZoneDrc ( ZONE_CONTAINER aArea,
int  aCornerIndex 
)
private

Function doEdgeZoneDrc tests a segment in ZONE_CONTAINER * aArea: Test Edge inside other areas Test Edge too close other areas.

Parameters
aAreaThe current area.
aCornerIndexThe first corner of the segment to test.
Returns
bool - false if DRC error or true if OK

Definition at line 609 of file drc_clearance_test_functions.cpp.

References SEG::A, SEG::B, SHAPE_POLY_SET::Contains(), COPPERAREA_CLOSE_TO_COPPERAREA, COPPERAREA_INSIDE_COPPERAREA, fillMarker(), BOARD::GetArea(), BOARD::GetAreaCount(), GetClearanceBetweenSegments(), ZONE_CONTAINER::GetIsKeepout(), ZONE_CONTAINER::GetLayer(), BOARD_CONNECTED_ITEM::GetNetCode(), ZONE_CONTAINER::GetPriority(), SHAPE_POLY_SET::GetRelativeIndices(), ZONE_CONTAINER::GetZoneClearance(), ZONE_CONTAINER::IsOnCopperLayer(), SHAPE_POLY_SET::IterateSegmentsWithHoles(), SHAPE_POLY_SET::VERTEX_INDEX::m_contour, m_currentMarker, m_pcb, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, SHAPE_POLY_SET::VERTEX_INDEX::m_vertex, max, ZONE_CONTAINER::Outline(), SHAPE_POLY_SET::Polygon(), SHAPE_LINE_CHAIN::Segment(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Drc().

610 {
611  if( !aArea->IsOnCopperLayer() ) // Cannot have a Drc error if not on copper layer
612  return true;
613  // Get polygon, contour and vertex index.
615 
616  // If the vertex does not exist, there is no conflict
617  if( !aArea->Outline()->GetRelativeIndices( aCornerIndex, &index ) )
618  return true;
619 
620  // Retrieve the selected contour
621  SHAPE_LINE_CHAIN contour;
622  contour = aArea->Outline()->Polygon( index.m_polygon )[index.m_contour];
623 
624  // Retrieve the segment that starts at aCornerIndex-th corner.
625  SEG selectedSegment = contour.Segment( index.m_vertex );
626 
627  VECTOR2I start = selectedSegment.A;
628  VECTOR2I end = selectedSegment.B;
629 
630  // iterate through all areas
631  for( int ia2 = 0; ia2 < m_pcb->GetAreaCount(); ia2++ )
632  {
633  ZONE_CONTAINER* area_to_test = m_pcb->GetArea( ia2 );
634  int zone_clearance = std::max( area_to_test->GetZoneClearance(),
635  aArea->GetZoneClearance() );
636 
637  // test for same layer
638  if( area_to_test->GetLayer() != aArea->GetLayer() )
639  continue;
640 
641  // Test for same net
642  if( ( aArea->GetNetCode() == area_to_test->GetNetCode() ) && (aArea->GetNetCode() >= 0) )
643  continue;
644 
645  // test for same priority
646  if( area_to_test->GetPriority() != aArea->GetPriority() )
647  continue;
648 
649  // test for same type
650  if( area_to_test->GetIsKeepout() != aArea->GetIsKeepout() )
651  continue;
652 
653  // For keepout, there is no clearance, so use a minimal value for it
654  // use 1, not 0 as value to avoid some issues in tests
655  if( area_to_test->GetIsKeepout() )
656  zone_clearance = 1;
657 
658  // test for ending line inside area_to_test
659  if( area_to_test->Outline()->Contains( end ) )
660  {
661  // COPPERAREA_COPPERAREA error: corner inside copper area
662  m_currentMarker = fillMarker( aArea, static_cast<wxPoint>( end ),
664  m_currentMarker );
665  return false;
666  }
667 
668  // now test spacing between areas
669  int ax1 = start.x;
670  int ay1 = start.y;
671  int ax2 = end.x;
672  int ay2 = end.y;
673 
674  // Iterate through all edges in the polygon.
676  for( iterator = area_to_test->Outline()->IterateSegmentsWithHoles(); iterator; iterator++ )
677  {
678  SEG segment = *iterator;
679 
680  int bx1 = segment.A.x;
681  int by1 = segment.A.y;
682  int bx2 = segment.B.x;
683  int by2 = segment.B.y;
684 
685  int x, y; // variables containing the intersecting point coordinates
686  int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
687  0,
688  ax1, ay1, ax2, ay2,
689  0,
690  zone_clearance,
691  &x, &y );
692 
693  if( d < zone_clearance )
694  {
695  // COPPERAREA_COPPERAREA error : edge intersect or too close
696  m_currentMarker = fillMarker( aArea, wxPoint( x, y ),
698  m_currentMarker );
699  return false;
700  }
701 
702  }
703  }
704 
705  return true;
706 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
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...
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:172
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:236
#define COPPERAREA_CLOSE_TO_COPPERAREA
copper area outlines are too close
Definition: drc_stuff.h:66
Struct VERTEX_INDEX.
Class SEGMENT_ITERATOR_TEMPLATE.
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)
BOARD * m_pcb
Definition: drc_stuff.h:211
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:602
bool GetRelativeIndices(int aGlobalIdx, VERTEX_INDEX *aRelativeIndices) const
Function GetRelativeIndices.
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
int GetNetCode() const
Function GetNetCode.
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
Definition: seg.h:36
SEG Segment(int aIndex)
Function Segment()
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.cpp:178
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
#define max(a, b)
Definition: auxiliary.h:86
Class SHAPE_LINE_CHAIN.
VECTOR2I A
Definition: seg.h:46
POLYGON & Polygon(int aIndex)
Returns the aIndex-th subpolygon in the set
unsigned GetPriority() const
Function GetPriority.
Definition: class_zone.h:101
int GetZoneClearance() const
Definition: class_zone.h:192
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:65
VECTOR2I B
Definition: seg.h:47
bool DRC::doFootprintOverlappingDrc ( )
private

Function doFootprintOverlappingDrc tests for footprint courtyard overlaps.

Returns
bool - false if DRC error or true if OK

Definition at line 1144 of file drc.cpp.

References addMarkerToPcb(), SHAPE_POLY_SET::Append(), SHAPE_POLY_SET::BooleanIntersection(), DRCE_MALFORMED_COURTYARD_IN_FOOTPRINT, DRCE_MISSING_COURTYARD_IN_FOOTPRINT, DRCE_OVERLAPPING_FOOTPRINTS, fillMarker(), m_currentMarker, m_doFootprintOverlapping, m_doNoCourtyardDefined, BOARD::m_Modules, m_pcb, MODULE::Next(), SHAPE_POLY_SET::OutlineCount(), SHAPE_POLY_SET::PM_FAST, SHAPE_POLY_SET::RemoveAllContours(), SHAPE_POLY_SET::Vertex(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by RunTests().

1145 {
1146  // Detects missing (or malformed) footprint courtyard,
1147  // and for footprint with courtyard, courtyards overlap.
1148  wxString msg;
1149  bool success = true;
1150 
1151  // Update courtyard polygons, and test for missing courtyard definition:
1152  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1153  {
1154  bool is_ok = footprint->BuildPolyCourtyard();
1155 
1156  if( !is_ok && m_doFootprintOverlapping )
1157  {
1158  msg.Printf( _( "footprint \"%s\" has malformed courtyard" ),
1159  footprint->GetReference().GetData() );
1160  m_currentMarker = fillMarker( footprint->GetPosition(),
1162  msg, m_currentMarker );
1164  m_currentMarker = nullptr;
1165  success = false;
1166  }
1167 
1168  if( !m_doNoCourtyardDefined )
1169  continue;
1170 
1171  if( footprint->GetPolyCourtyardFront().OutlineCount() == 0 &&
1172  footprint->GetPolyCourtyardBack().OutlineCount() == 0 &&
1173  is_ok )
1174  {
1175  msg.Printf( _( "footprint \"%s\" has no courtyard defined" ),
1176  footprint->GetReference().GetData() );
1177  m_currentMarker = fillMarker( footprint->GetPosition(),
1179  msg, m_currentMarker );
1181  m_currentMarker = nullptr;
1182  success = false;
1183  }
1184  }
1185 
1187  return success;
1188 
1189  // Now test for overlapping on top layer:
1190  SHAPE_POLY_SET courtyard; // temporary storage of the courtyard of current footprint
1191 
1192  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1193  {
1194  if( footprint->GetPolyCourtyardFront().OutlineCount() == 0 )
1195  continue; // No courtyard defined
1196 
1197  for( MODULE* candidate = footprint->Next(); candidate; candidate = candidate->Next() )
1198  {
1199  if( candidate->GetPolyCourtyardFront().OutlineCount() == 0 )
1200  continue; // No courtyard defined
1201 
1202  courtyard.RemoveAllContours();
1203  courtyard.Append( footprint->GetPolyCourtyardFront() );
1204 
1205  // Build the common area between footprint and the candidate:
1206  courtyard.BooleanIntersection( candidate->GetPolyCourtyardFront(), SHAPE_POLY_SET::PM_FAST );
1207 
1208  // If no overlap, courtyard is empty (no common area).
1209  // Therefore if a common polygon exists, this is a DRC error
1210  if( courtyard.OutlineCount() )
1211  {
1212  //Overlap between footprint and candidate
1213  msg.Printf( _( "footprints \"%s\" and \"%s\" overlap on front (top) layer" ),
1214  footprint->GetReference().GetData(),
1215  candidate->GetReference().GetData() );
1216  VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 );
1217  wxPoint loc( pos.x, pos.y );
1220  m_currentMarker = nullptr;
1221  success = false;
1222  }
1223  }
1224  }
1225 
1226  // Test for overlapping on bottom layer:
1227  for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() )
1228  {
1229  if( footprint->GetPolyCourtyardBack().OutlineCount() == 0 )
1230  continue; // No courtyard defined
1231 
1232  for( MODULE* candidate = footprint->Next(); candidate; candidate = candidate->Next() )
1233  {
1234  if( candidate->GetPolyCourtyardBack().OutlineCount() == 0 )
1235  continue; // No courtyard defined
1236 
1237  courtyard.RemoveAllContours();
1238  courtyard.Append( footprint->GetPolyCourtyardBack() );
1239 
1240  // Build the common area between footprint and the candidate:
1241  courtyard.BooleanIntersection( candidate->GetPolyCourtyardBack(), SHAPE_POLY_SET::PM_FAST );
1242 
1243  // If no overlap, courtyard is empty (no common area).
1244  // Therefore if a common polygon exists, this is a DRC error
1245  if( courtyard.OutlineCount() )
1246  {
1247  //Overlap between footprint and candidate
1248  msg.Printf( _( "footprints \"%s\" and \"%s\" overlap on back (bottom) layer" ),
1249  footprint->GetReference().GetData(),
1250  candidate->GetReference().GetData() );
1251  VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 );
1252  wxPoint loc( pos.x, pos.y );
1255  m_currentMarker = nullptr;
1256  success = false;
1257  }
1258  }
1259  }
1260 
1261  return success;
1262 }
bool m_doNoCourtyardDefined
Definition: drc_stuff.h:178
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...
MODULE * Next() const
Definition: class_module.h:120
#define DRCE_MISSING_COURTYARD_IN_FOOTPRINT
footprint has no courtyard defined
Definition: drc_stuff.h:88
int OutlineCount() const
Returns the number of outlines in the set
BOARD * m_pcb
Definition: drc_stuff.h:211
bool m_doFootprintOverlapping
Definition: drc_stuff.h:177
VECTOR2I & Vertex(int aIndex, int aOutline, int aHole)
Returns the index-th vertex in a given hole outline within a given outline
void addMarkerToPcb(MARKER_PCB *aMarker)
Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism.
Definition: drc.cpp:94
Class SHAPE_POLY_SET.
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset intersection For aFastMode meaning, see function booleanOp ...
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
#define DRCE_OVERLAPPING_FOOTPRINTS
footprint courtyards overlap
Definition: drc_stuff.h:87
DLIST< MODULE > m_Modules
Definition: class_board.h:245
#define DRCE_MALFORMED_COURTYARD_IN_FOOTPRINT
footprint has a courtyard but malformed
Definition: drc_stuff.h:89
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
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) ...
bool DRC::doNetClass ( const std::shared_ptr< NETCLASS > &  aNetClass,
wxString &  msg 
)
private

Definition at line 505 of file drc.cpp.

References addMarkerToPcb(), DRCE_NETCLASS_CLEARANCE, DRCE_NETCLASS_TRACKWIDTH, DRCE_NETCLASS_uVIADRILLSIZE, DRCE_NETCLASS_uVIASIZE, DRCE_NETCLASS_VIADRILLSIZE, DRCE_NETCLASS_VIASIZE, fillMarker(), FmtVal, GetChars(), BOARD::GetDesignSettings(), m_currentMarker, BOARD_DESIGN_SETTINGS::m_MicroViasMinDrill, BOARD_DESIGN_SETTINGS::m_MicroViasMinSize, m_pcb, BOARD_DESIGN_SETTINGS::m_TrackMinWidth, BOARD_DESIGN_SETTINGS::m_ViasMinDrill, and BOARD_DESIGN_SETTINGS::m_ViasMinSize.

Referenced by testNetClasses().

506 {
507  bool ret = true;
508 
510 
511 #define FmtVal( x ) GetChars( StringFromValue( g_UserUnit, x ) )
512 
513 #if 0 // set to 1 when (if...) BOARD_DESIGN_SETTINGS has a m_MinClearance value
514  if( nc->GetClearance() < g.m_MinClearance )
515  {
516  msg.Printf( _( "NETCLASS: \"%s\" has Clearance:%s which is less than global:%s" ),
517  GetChars( nc->GetName() ),
518  FmtVal( nc->GetClearance() ),
519  FmtVal( g.m_TrackClearance )
520  );
521 
523  m_currentMarker = nullptr;
524  ret = false;
525  }
526 #endif
527 
528  if( nc->GetTrackWidth() < g.m_TrackMinWidth )
529  {
530  msg.Printf( _( "NETCLASS: \"%s\" has TrackWidth:%s which is less than global:%s" ),
531  GetChars( nc->GetName() ),
532  FmtVal( nc->GetTrackWidth() ),
534  );
535 
537  m_currentMarker = nullptr;
538  ret = false;
539  }
540 
541  if( nc->GetViaDiameter() < g.m_ViasMinSize )
542  {
543  msg.Printf( _( "NETCLASS: \"%s\" has Via Dia:%s which is less than global:%s" ),
544  GetChars( nc->GetName() ),
545  FmtVal( nc->GetViaDiameter() ),
546  FmtVal( g.m_ViasMinSize )
547  );
548 
550  m_currentMarker = nullptr;
551  ret = false;
552  }
553 
554  if( nc->GetViaDrill() < g.m_ViasMinDrill )
555  {
556  msg.Printf( _( "NETCLASS: \"%s\" has Via Drill:%s which is less than global:%s" ),
557  GetChars( nc->GetName() ),
558  FmtVal( nc->GetViaDrill() ),
560  );
561 
563  m_currentMarker = nullptr;
564  ret = false;
565  }
566 
567  if( nc->GetuViaDiameter() < g.m_MicroViasMinSize )
568  {
569  msg.Printf( _( "NETCLASS: \"%s\" has uVia Dia:%s which is less than global:%s" ),
570  GetChars( nc->GetName() ),
571  FmtVal( nc->GetuViaDiameter() ),
573  );
574 
576  m_currentMarker = nullptr;
577  ret = false;
578  }
579 
580  if( nc->GetuViaDrill() < g.m_MicroViasMinDrill )
581  {
582  msg.Printf( _( "NETCLASS: \"%s\" has uVia Drill:%s which is less than global:%s" ),
583  GetChars( nc->GetName() ),
584  FmtVal( nc->GetuViaDrill() ),
586  );
587 
589  m_currentMarker = nullptr;
590  ret = false;
591  }
592 
593  return ret;
594 }
#define DRCE_NETCLASS_CLEARANCE
netclass has Clearance < board.m_designSettings->m_TrackClearance
Definition: drc_stuff.h:76
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...
BOARD * m_pcb
Definition: drc_stuff.h:211
void addMarkerToPcb(MARKER_PCB *aMarker)
Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism.
Definition: drc.cpp:94
#define DRCE_NETCLASS_uVIADRILLSIZE
netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill
Definition: drc_stuff.h:80
int m_TrackMinWidth
track min value for width ((min copper size value
int m_ViasMinSize
vias (not micro vias) min diameter
int m_ViasMinDrill
vias (not micro vias) min drill diameter
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
int m_MicroViasMinSize
micro vias (not vias) min diameter
#define FmtVal(x)
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
#define DRCE_NETCLASS_uVIASIZE
netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize
Definition: drc_stuff.h:79
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
#define DRCE_NETCLASS_TRACKWIDTH
netclass has TrackWidth < board.m_designSettings->m_TrackMinWidth
Definition: drc_stuff.h:75
#define DRCE_NETCLASS_VIASIZE
netclass has ViaSize < board.m_designSettings->m_ViasMinSize
Definition: drc_stuff.h:77
int m_MicroViasMinDrill
micro vias (not vias) min drill diameter
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
#define DRCE_NETCLASS_VIADRILLSIZE
netclass has ViaDrillSize < board.m_designSettings->m_ViasMinDrill
Definition: drc_stuff.h:78
bool DRC::doPadToPadsDrc ( D_PAD aRefPad,
D_PAD **  aStart,
D_PAD **  aEnd,
int  x_limit 
)
private

Function doPadToPadsDrc tests the clearance between aRefPad and other pads.

The pad list must be sorted by x coordinate.

Parameters
aRefPadThe pad to test
aStartThe start of the pad list to test against
aEndMarks the end of the list and is not included
x_limitis used to stop the test (when the any pad's X coord exceeds this)

Definition at line 1010 of file drc.cpp.

References LSET::AllCuMask(), checkClearancePadToPad(), DRCE_HOLE_NEAR_PAD, DRCE_PAD_NEAR_PAD1, fillMarker(), D_PAD::GetDrillShape(), D_PAD::GetDrillSize(), D_PAD::GetLayerSet(), BOARD_CONNECTED_ITEM::GetNetCode(), D_PAD::GetOrientation(), D_PAD::GetParent(), D_PAD::GetPosition(), m_currentMarker, m_pcb, PAD_DRILL_SHAPE_CIRCLE, PAD_DRILL_SHAPE_OBLONG, PAD_SHAPE_CIRCLE, PAD_SHAPE_OVAL, D_PAD::PadNameEqual(), D_PAD::SetLayerSet(), D_PAD::SetLocalClearance(), D_PAD::SetOrientation(), D_PAD::SetPosition(), D_PAD::SetShape(), D_PAD::SetSize(), and wxPoint::x.

Referenced by testPad2Pad().

1011 {
1012  const static LSET all_cu = LSET::AllCuMask();
1013 
1014  LSET layerMask = aRefPad->GetLayerSet() & all_cu;
1015 
1016  /* used to test DRC pad to holes: this dummy pad has the size and shape of the hole
1017  * to test pad to pad hole DRC, using the pad to pad DRC test function.
1018  * Therefore, this dummy pad is a circle or an oval.
1019  * A pad must have a parent because some functions expect a non null parent
1020  * to find the parent board, and some other data
1021  */
1022  MODULE dummymodule( m_pcb ); // Creates a dummy parent
1023  D_PAD dummypad( &dummymodule );
1024 
1025  // Ensure the hole is on all copper layers
1026  dummypad.SetLayerSet( all_cu | dummypad.GetLayerSet() );
1027 
1028  // Use the minimal local clearance value for the dummy pad.
1029  // The clearance of the active pad will be used as minimum distance to a hole
1030  // (a value = 0 means use netclass value)
1031  dummypad.SetLocalClearance( 1 );
1032 
1033  for( D_PAD** pad_list = aStart; pad_list<aEnd; ++pad_list )
1034  {
1035  D_PAD* pad = *pad_list;
1036 
1037  if( pad == aRefPad )
1038  continue;
1039 
1040  // We can stop the test when pad->GetPosition().x > x_limit
1041  // because the list is sorted by X values
1042  if( pad->GetPosition().x > x_limit )
1043  break;
1044 
1045  // No problem if pads which are on copper layers are on different copper layers,
1046  // (pads can be only on a technical layer, to build complex pads)
1047  // but their hole (if any ) can create DRC error because they are on all
1048  // copper layers, so we test them
1049  if( ( pad->GetLayerSet() & layerMask ) == 0 &&
1050  ( pad->GetLayerSet() & all_cu ) != 0 &&
1051  ( aRefPad->GetLayerSet() & all_cu ) != 0 )
1052  {
1053  // if holes are in the same location and have the same size and shape,
1054  // this can be accepted
1055  if( pad->GetPosition() == aRefPad->GetPosition()
1056  && pad->GetDrillSize() == aRefPad->GetDrillSize()
1057  && pad->GetDrillShape() == aRefPad->GetDrillShape() )
1058  {
1059  if( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
1060  continue;
1061 
1062  // for oval holes: must also have the same orientation
1063  if( pad->GetOrientation() == aRefPad->GetOrientation() )
1064  continue;
1065  }
1066 
1067  /* Here, we must test clearance between holes and pads
1068  * dummy pad size and shape is adjusted to pad drill size and shape
1069  */
1070  if( pad->GetDrillSize().x )
1071  {
1072  // pad under testing has a hole, test this hole against pad reference
1073  dummypad.SetPosition( pad->GetPosition() );
1074  dummypad.SetSize( pad->GetDrillSize() );
1075  dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
1077  dummypad.SetOrientation( pad->GetOrientation() );
1078 
1079  if( !checkClearancePadToPad( aRefPad, &dummypad ) )
1080  {
1081  // here we have a drc error on pad!
1082  m_currentMarker = fillMarker( pad, aRefPad,
1084  return false;
1085  }
1086  }
1087 
1088  if( aRefPad->GetDrillSize().x ) // pad reference has a hole
1089  {
1090  dummypad.SetPosition( aRefPad->GetPosition() );
1091  dummypad.SetSize( aRefPad->GetDrillSize() );
1092  dummypad.SetShape( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
1094  dummypad.SetOrientation( aRefPad->GetOrientation() );
1095 
1096  if( !checkClearancePadToPad( pad, &dummypad ) )
1097  {
1098  // here we have a drc error on aRefPad!
1099  m_currentMarker = fillMarker( aRefPad, pad,
1101  return false;
1102  }
1103  }
1104 
1105  continue;
1106  }
1107 
1108  // The pad must be in a net (i.e pt_pad->GetNet() != 0 ),
1109  // But no problem if pads have the same netcode (same net)
1110  if( pad->GetNetCode() && ( aRefPad->GetNetCode() == pad->GetNetCode() ) )
1111  continue;
1112 
1113  // if pads are from the same footprint
1114  if( pad->GetParent() == aRefPad->GetParent() )
1115  {
1116  // and have the same pad number ( equivalent pads )
1117 
1118  // one can argue that this 2nd test is not necessary, that any
1119  // two pads from a single module are acceptable. This 2nd test
1120  // should eventually be a configuration option.
1121  if( pad->PadNameEqual( aRefPad ) )
1122  continue;
1123  }
1124 
1125  // if either pad has no drill and is only on technical layers, not a clearance violation
1126  if( ( ( pad->GetLayerSet() & layerMask ) == 0 && !pad->GetDrillSize().x ) ||
1127  ( ( aRefPad->GetLayerSet() & layerMask ) == 0 && !aRefPad->GetDrillSize().x ) )
1128  {
1129  continue;
1130  }
1131 
1132  if( !checkClearancePadToPad( aRefPad, pad ) )
1133  {
1134  // here we have a drc error!
1136  return false;
1137  }
1138  }
1139 
1140  return true;
1141 }
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 PadNameEqual(const D_PAD *other) const
Definition: class_pad.h:207
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...
#define DRCE_PAD_NEAR_PAD1
pad too close to pad
Definition: drc_stuff.h:62
MODULE * GetParent() const
Definition: class_pad.h:162
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:219
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:381
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
BOARD * m_pcb
Definition: drc_stuff.h:211
Class LSET is a set of PCB_LAYER_IDs.
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 GetNetCode() const
Function GetNetCode.
bool checkClearancePadToPad(D_PAD *aRefPad, D_PAD *aPad)
Function checkClearancePadToPad.
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:375
const wxPoint GetPosition() const override
Definition: class_pad.h:220
#define DRCE_HOLE_NEAR_PAD
hole too close to pad
Definition: drc_stuff.h:68
bool DRC::doTrackDrc ( TRACK aRefSeg,
TRACK aStart,
bool  doPads = true 
)
private

Function DoTrackDrc tests the current segment.

Parameters
aRefSegThe segment to test
aStartThe head of a list of tracks to test against (usually BOARD::m_Track)
doPadstrue if should do pads test
Returns
bool - true if no poblems, else false and m_currentMarker is filled in with the problem information.

Definition at line 137 of file drc_clearance_test_functions.cpp.

References abs, LSET::AllCuMask(), PNS::angle(), ArcTangente(), B_Cu, checkClearanceSegmToPad(), checkLine(), checkMarginToCircle(), delta, DRCE_BURIED_VIA_NOT_ALLOWED, DRCE_ENDS_PROBLEM1, DRCE_ENDS_PROBLEM2, DRCE_ENDS_PROBLEM3, DRCE_ENDS_PROBLEM4, DRCE_ENDS_PROBLEM5, DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, DRCE_MICRO_VIA_NOT_ALLOWED, DRCE_TOO_SMALL_MICROVIA, DRCE_TOO_SMALL_MICROVIA_DRILL, DRCE_TOO_SMALL_TRACK_WIDTH, DRCE_TOO_SMALL_VIA, DRCE_TOO_SMALL_VIA_DRILL, DRCE_TRACK_ENDS1, DRCE_TRACK_ENDS2, DRCE_TRACK_ENDS3, DRCE_TRACK_ENDS4, DRCE_TRACK_NEAR_PAD, DRCE_TRACK_NEAR_THROUGH_HOLE, DRCE_TRACK_NEAR_VIA, DRCE_TRACK_SEGMENTS_TOO_CLOSE, DRCE_TRACKS_CROSSING, DRCE_VIA_HOLE_BIGGER, DRCE_VIA_NEAR_TRACK, DRCE_VIA_NEAR_VIA, EuclideanNorm(), F_Cu, fillMarker(), TRACK::GetClearance(), BOARD_DESIGN_SETTINGS::GetCopperLayerCount(), BOARD::GetDesignSettings(), D_PAD::GetDrillShape(), D_PAD::GetDrillSize(), VIA::GetDrillValue(), TRACK::GetEnd(), BOARD_ITEM::GetLayerSet(), D_PAD::GetLayerSet(), BOARD_CONNECTED_ITEM::GetNetClass(), BOARD_CONNECTED_ITEM::GetNetCode(), D_PAD::GetOrientation(), BOARD::GetPadCount(), BOARD::GetPads(), D_PAD::GetPosition(), TRACK::GetStart(), VIA::GetViaType(), TRACK::GetWidth(), In1_Cu, VIA::LayerPair(), BOARD_DESIGN_SETTINGS::m_BlindBuriedViaAllowed, m_currentMarker, BOARD_DESIGN_SETTINGS::m_MicroViasAllowed, BOARD_DESIGN_SETTINGS::m_MicroViasMinDrill, BOARD_DESIGN_SETTINGS::m_MicroViasMinSize, m_padToTestPos, m_pcb, m_segmAngle, m_segmEnd, m_segmLength, BOARD_DESIGN_SETTINGS::m_TrackMinWidth, BOARD_DESIGN_SETTINGS::m_ViasMinDrill, BOARD_DESIGN_SETTINGS::m_ViasMinSize, m_xcliphi, m_xcliplo, m_ycliphi, m_ycliplo, TRACK::Next(), PAD_DRILL_SHAPE_OBLONG, PAD_SHAPE_CIRCLE, PAD_SHAPE_OVAL, PCB_VIA_T, RotatePoint(), D_PAD::SetLayerSet(), D_PAD::SetOrientation(), D_PAD::SetPosition(), D_PAD::SetShape(), D_PAD::SetSize(), D_PAD::ShapePos(), EDA_ITEM::Type(), VIA_BLIND_BURIED, VIA_MICROVIA, wxPoint::x, and wxPoint::y.

Referenced by Drc(), DrcBlind(), and testTracks().

138 {
139  TRACK* track;
140  wxPoint delta; // length on X and Y axis of segments
141  LSET layerMask;
142  int net_code_ref;
143  wxPoint shape_pos;
144 
145  NETCLASSPTR netclass = aRefSeg->GetNetClass();
147 
148  /* In order to make some calculations more easier or faster,
149  * pads and tracks coordinates will be made relative to the reference segment origin
150  */
151  wxPoint origin = aRefSeg->GetStart(); // origin will be the origin of other coordinates
152 
153  m_segmEnd = delta = aRefSeg->GetEnd() - origin;
154  m_segmAngle = 0;
155 
156  layerMask = aRefSeg->GetLayerSet();
157  net_code_ref = aRefSeg->GetNetCode();
158 
159  // Phase 0 : Test vias
160  if( aRefSeg->Type() == PCB_VIA_T )
161  {
162  const VIA *refvia = static_cast<const VIA*>( aRefSeg );
163  // test if the via size is smaller than minimum
164  if( refvia->GetViaType() == VIA_MICROVIA )
165  {
166  if( refvia->GetWidth() < dsnSettings.m_MicroViasMinSize )
167  {
168  m_currentMarker = fillMarker( refvia, NULL,
170  return false;
171  }
172  if( refvia->GetDrillValue() < dsnSettings.m_MicroViasMinDrill )
173  {
174  m_currentMarker = fillMarker( refvia, NULL,
176  return false;
177  }
178  }
179  else
180  {
181  if( refvia->GetWidth() < dsnSettings.m_ViasMinSize )
182  {
183  m_currentMarker = fillMarker( refvia, NULL,
185  return false;
186  }
187  if( refvia->GetDrillValue() < dsnSettings.m_ViasMinDrill )
188  {
189  m_currentMarker = fillMarker( refvia, NULL,
191  return false;
192  }
193  }
194 
195  // test if via's hole is bigger than its diameter
196  // This test is necessary since the via hole size and width can be modified
197  // and a default via hole can be bigger than some vias sizes
198  if( refvia->GetDrillValue() > refvia->GetWidth() )
199  {
200  m_currentMarker = fillMarker( refvia, NULL,
202  return false;
203  }
204 
205  // test if the type of via is allowed due to design rules
206  if( ( refvia->GetViaType() == VIA_MICROVIA ) &&
207  ( m_pcb->GetDesignSettings().m_MicroViasAllowed == false ) )
208  {
209  m_currentMarker = fillMarker( refvia, NULL,
211  return false;
212  }
213 
214  // test if the type of via is allowed due to design rules
215  if( ( refvia->GetViaType() == VIA_BLIND_BURIED ) &&
217  {
218  m_currentMarker = fillMarker( refvia, NULL,
220  return false;
221  }
222 
223  // For microvias: test if they are blind vias and only between 2 layers
224  // because they are used for very small drill size and are drill by laser
225  // and **only one layer** can be drilled
226  if( refvia->GetViaType() == VIA_MICROVIA )
227  {
228 
229 
230  PCB_LAYER_ID layer1, layer2;
231  bool err = true;
232 
233  refvia->LayerPair( &layer1, &layer2 );
234 
235  if( layer1 > layer2 )
236  std::swap( layer1, layer2 );
237 
238  if( layer2 == B_Cu && layer1 == m_pcb->GetDesignSettings().GetCopperLayerCount() - 2 )
239  err = false;
240  else if( layer1 == F_Cu && layer2 == In1_Cu )
241  err = false;
242 
243  if( err )
244  {
245  m_currentMarker = fillMarker( refvia, NULL,
247  return false;
248  }
249  }
250 
251  }
252  else // This is a track segment
253  {
254  if( aRefSeg->GetWidth() < dsnSettings.m_TrackMinWidth )
255  {
256  m_currentMarker = fillMarker( aRefSeg, NULL,
258  return false;
259  }
260  }
261 
262  // for a non horizontal or vertical segment Compute the segment angle
263  // in tenths of degrees and its length
264  if( delta.x || delta.y )
265  {
266  // Compute the segment angle in 0,1 degrees
267  m_segmAngle = ArcTangente( delta.y, delta.x );
268 
269  // Compute the segment length: we build an equivalent rotated segment,
270  // this segment is horizontal, therefore dx = length
271  RotatePoint( &delta, m_segmAngle ); // delta.x = length, delta.y = 0
272  }
273 
274  m_segmLength = delta.x;
275 
276  /******************************************/
277  /* Phase 1 : test DRC track to pads : */
278  /******************************************/
279 
280  /* Use a dummy pad to test DRC tracks versus holes, for pads not on all copper layers
281  * but having a hole
282  * This dummy pad has the size and shape of the hole
283  * to test tracks to pad hole DRC, using checkClearanceSegmToPad test function.
284  * Therefore, this dummy pad is a circle or an oval.
285  * A pad must have a parent because some functions expect a non null parent
286  * to find the parent board, and some other data
287  */
288  MODULE dummymodule( m_pcb ); // Creates a dummy parent
289  D_PAD dummypad( &dummymodule );
290 
291  dummypad.SetLayerSet( LSET::AllCuMask() ); // Ensure the hole is on all layers
292 
293  // Compute the min distance to pads
294  if( testPads )
295  {
296  unsigned pad_count = m_pcb->GetPadCount();
297 
298  auto pads = m_pcb->GetPads();
299 
300  for( unsigned ii = 0; ii<pad_count; ++ii )
301  {
302  D_PAD* pad = pads[ii];
303 
304  /* No problem if pads are on an other layer,
305  * But if a drill hole exists (a pad on a single layer can have a hole!)
306  * we must test the hole
307  */
308  if( !( pad->GetLayerSet() & layerMask ).any() )
309  {
310  /* We must test the pad hole. In order to use the function
311  * checkClearanceSegmToPad(),a pseudo pad is used, with a shape and a
312  * size like the hole
313  */
314  if( pad->GetDrillSize().x == 0 )
315  continue;
316 
317  dummypad.SetSize( pad->GetDrillSize() );
318  dummypad.SetPosition( pad->GetPosition() );
319  dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
321  dummypad.SetOrientation( pad->GetOrientation() );
322 
323  m_padToTestPos = dummypad.GetPosition() - origin;
324 
325  if( !checkClearanceSegmToPad( &dummypad, aRefSeg->GetWidth(),
326  netclass->GetClearance() ) )
327  {
328  m_currentMarker = fillMarker( aRefSeg, pad,
330  return false;
331  }
332 
333  continue;
334  }
335 
336  // The pad must be in a net (i.e pt_pad->GetNet() != 0 )
337  // but no problem if the pad netcode is the current netcode (same net)
338  if( pad->GetNetCode() // the pad must be connected
339  && net_code_ref == pad->GetNetCode() ) // the pad net is the same as current net -> Ok
340  continue;
341 
342  // DRC for the pad
343  shape_pos = pad->ShapePos();
344  m_padToTestPos = shape_pos - origin;
345 
346  if( !checkClearanceSegmToPad( pad, aRefSeg->GetWidth(), aRefSeg->GetClearance( pad ) ) )
347  {
348  m_currentMarker = fillMarker( aRefSeg, pad,
350  return false;
351  }
352  }
353  }
354 
355  /***********************************************/
356  /* Phase 2: test DRC with other track segments */
357  /***********************************************/
358 
359  // At this point the reference segment is the X axis
360 
361  // Test the reference segment with other track segments
362  wxPoint segStartPoint;
363  wxPoint segEndPoint;
364  for( track = aStart; track; track = track->Next() )
365  {
366  // No problem if segments have the same net code:
367  if( net_code_ref == track->GetNetCode() )
368  continue;
369 
370  // No problem if segment are on different layers :
371  if( !( layerMask & track->GetLayerSet() ).any() )
372  continue;
373 
374  // the minimum distance = clearance plus half the reference track
375  // width plus half the other track's width
376  int w_dist = aRefSeg->GetClearance( track );
377  w_dist += (aRefSeg->GetWidth() + track->GetWidth()) / 2;
378 
379  // Due to many double to int conversions during calculations, which
380  // create rounding issues,
381  // the exact clearance margin cannot be really known.
382  // To avoid false bad DRC detection due to these rounding issues,
383  // slightly decrease the w_dist (remove one nanometer is enough !)
384  w_dist -= 1;
385 
386  // If the reference segment is a via, we test it here
387  if( aRefSeg->Type() == PCB_VIA_T )
388  {
389  delta = track->GetEnd() - track->GetStart();
390  segStartPoint = aRefSeg->GetStart() - track->GetStart();
391 
392  if( track->Type() == PCB_VIA_T )
393  {
394  // Test distance between two vias, i.e. two circles, trivial case
395  if( EuclideanNorm( segStartPoint ) < w_dist )
396  {
397  m_currentMarker = fillMarker( aRefSeg, track,
399  return false;
400  }
401  }
402  else // test via to segment
403  {
404  // Compute l'angle du segment a tester;
405  double angle = ArcTangente( delta.y, delta.x );
406 
407  // Compute new coordinates ( the segment become horizontal)
408  RotatePoint( &delta, angle );
409  RotatePoint( &segStartPoint, angle );
410 
411  if( !checkMarginToCircle( segStartPoint, w_dist, delta.x ) )
412  {
413  m_currentMarker = fillMarker( track, aRefSeg,
415  return false;
416  }
417  }
418 
419  continue;
420  }
421 
422  /* We compute segStartPoint, segEndPoint = starting and ending point coordinates for
423  * the segment to test in the new axis : the new X axis is the
424  * reference segment. We must translate and rotate the segment to test
425  */
426  segStartPoint = track->GetStart() - origin;
427  segEndPoint = track->GetEnd() - origin;
428  RotatePoint( &segStartPoint, m_segmAngle );
429  RotatePoint( &segEndPoint, m_segmAngle );
430  if( track->Type() == PCB_VIA_T )
431  {
432  if( checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
433  continue;
434 
435  m_currentMarker = fillMarker( aRefSeg, track,
437  return false;
438  }
439 
440  /* We have changed axis:
441  * the reference segment is Horizontal.
442  * 3 cases : the segment to test can be parallel, perpendicular or have an other direction
443  */
444  if( segStartPoint.y == segEndPoint.y ) // parallel segments
445  {
446  if( abs( segStartPoint.y ) >= w_dist )
447  continue;
448 
449  // Ensure segStartPoint.x <= segEndPoint.x
450  if( segStartPoint.x > segEndPoint.x )
451  std::swap( segStartPoint.x, segEndPoint.x );
452 
453  if( segStartPoint.x > (-w_dist) && segStartPoint.x < (m_segmLength + w_dist) ) /* possible error drc */
454  {
455  // the start point is inside the reference range
456  // X........
457  // O--REF--+
458 
459  // Fine test : we consider the rounded shape of each end of the track segment:
460  if( segStartPoint.x >= 0 && segStartPoint.x <= m_segmLength )
461  {
462  m_currentMarker = fillMarker( aRefSeg, track,
464  return false;
465  }
466 
467  if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
468  {
469  m_currentMarker = fillMarker( aRefSeg, track,
471  return false;
472  }
473  }
474 
475  if( segEndPoint.x > (-w_dist) && segEndPoint.x < (m_segmLength + w_dist) )
476  {
477  // the end point is inside the reference range
478  // .....X
479  // O--REF--+
480  // Fine test : we consider the rounded shape of the ends
481  if( segEndPoint.x >= 0 && segEndPoint.x <= m_segmLength )
482  {
483  m_currentMarker = fillMarker( aRefSeg, track,
485  return false;
486  }
487 
488  if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
489  {
490  m_currentMarker = fillMarker( aRefSeg, track,
492  return false;
493  }
494  }
495 
496  if( segStartPoint.x <=0 && segEndPoint.x >= 0 )
497  {
498  // the segment straddles the reference range (this actually only
499  // checks if it straddles the origin, because the other cases where already
500  // handled)
501  // X.............X
502  // O--REF--+
503  m_currentMarker = fillMarker( aRefSeg, track,
505  return false;
506  }
507  }
508  else if( segStartPoint.x == segEndPoint.x ) // perpendicular segments
509  {
510  if( ( segStartPoint.x <= (-w_dist) ) || ( segStartPoint.x >= (m_segmLength + w_dist) ) )
511  continue;
512 
513  // Test if segments are crossing
514  if( segStartPoint.y > segEndPoint.y )
515  std::swap( segStartPoint.y, segEndPoint.y );
516 
517  if( (segStartPoint.y < 0) && (segEndPoint.y > 0) )
518  {
519  m_currentMarker = fillMarker( aRefSeg, track,
521  return false;
522  }
523 
524  // At this point the drc error is due to an end near a reference segm end
525  if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
526  {
527  m_currentMarker = fillMarker( aRefSeg, track,
529  return false;
530  }
531  if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
532  {
533  m_currentMarker = fillMarker( aRefSeg, track,
535  return false;
536  }
537  }
538  else // segments quelconques entre eux
539  {
540  // calcul de la "surface de securite du segment de reference
541  // First rought 'and fast) test : the track segment is like a rectangle
542 
543  m_xcliplo = m_ycliplo = -w_dist;
544  m_xcliphi = m_segmLength + w_dist;
545  m_ycliphi = w_dist;
546 
547  // A fine test is needed because a serment is not exactly a
548  // rectangle, it has rounded ends
549  if( !checkLine( segStartPoint, segEndPoint ) )
550  {
551  /* 2eme passe : the track has rounded ends.
552  * we must a fine test for each rounded end and the
553  * rectangular zone
554  */
555 
556  m_xcliplo = 0;
558 
559  if( !checkLine( segStartPoint, segEndPoint ) )
560  {
561  m_currentMarker = fillMarker( aRefSeg, track,
563  return false;
564  }
565  else // The drc error is due to the starting or the ending point of the reference segment
566  {
567  // Test the starting and the ending point
568  segStartPoint = track->GetStart();
569  segEndPoint = track->GetEnd();
570  delta = segEndPoint - segStartPoint;
571 
572  // Compute the segment orientation (angle) en 0,1 degre
573  double angle = ArcTangente( delta.y, delta.x );
574 
575  // Compute the segment length: delta.x = length after rotation
576  RotatePoint( &delta, angle );
577 
578  /* Comute the reference segment coordinates relatives to a
579  * X axis = current tested segment
580  */
581  wxPoint relStartPos = aRefSeg->GetStart() - segStartPoint;
582  wxPoint relEndPos = aRefSeg->GetEnd() - segStartPoint;
583 
584  RotatePoint( &relStartPos, angle );
585  RotatePoint( &relEndPos, angle );
586 
587  if( !checkMarginToCircle( relStartPos, w_dist, delta.x ) )
588  {
589  m_currentMarker = fillMarker( aRefSeg, track,
591  return false;
592  }
593 
594  if( !checkMarginToCircle( relEndPos, w_dist, delta.x ) )
595  {
596  m_currentMarker = fillMarker( aRefSeg, track,
598  return false;
599  }
600  }
601  }
602  }
603  }
604 
605  return true;
606 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
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
KICAD_T Type() const
Function Type()
Definition: base_struct.h:225
#define DRCE_TRACK_SEGMENTS_TOO_CLOSE
2 parallel track segments too close: segm ends between segref ends
Definition: drc_stuff.h:55
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...
int m_ycliplo
Definition: drc_stuff.h:206
#define DRCE_ENDS_PROBLEM1
track ends are too close
Definition: drc_stuff.h:57
#define DRCE_TRACK_ENDS1
2 parallel track segments too close: fine start point test
Definition: drc_stuff.h:51
#define DRCE_TOO_SMALL_MICROVIA_DRILL
Too small micro via drill.
Definition: drc_stuff.h:74
#define DRCE_TRACK_NEAR_VIA
track too close to via
Definition: drc_stuff.h:48
int m_ycliphi
Definition: drc_stuff.h:208
int m_segmLength
Definition: drc_stuff.h:200
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:381
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
const wxSize & GetDrillSize() const
Definition: class_pad.h:275
#define DRCE_MICRO_VIA_NOT_ALLOWED
micro vias are not allowed
Definition: drc_stuff.h:91
#define DRCE_TRACKS_CROSSING
tracks are crossing
Definition: drc_stuff.h:56
wxPoint m_padToTestPos
Definition: drc_stuff.h:191
#define DRCE_ENDS_PROBLEM2
track ends are too close
Definition: drc_stuff.h:58
#define abs(a)
Definition: auxiliary.h:84
#define DRCE_TOO_SMALL_MICROVIA
Too small micro via size.
Definition: drc_stuff.h:72
static const int delta[8][2]
Definition: solve.cpp:112
const wxPoint & GetEnd() const
Definition: class_track.h:120
BOARD * m_pcb
Definition: drc_stuff.h:211
bool checkLine(wxPoint aSegStart, wxPoint aSegEnd)
Function checkLine (helper function used in drc calculations to see if one track is in contact with a...
#define DRCE_ENDS_PROBLEM5
track ends are too close
Definition: drc_stuff.h:61
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
int GetCopperLayerCount() const
Function GetCopperLayerCount.
VIATYPE_T GetViaType() const
Definition: class_track.h:456
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:271
#define DRCE_VIA_NEAR_TRACK
via too close to track
Definition: drc_stuff.h:50
std::shared_ptr< NETCLASS > GetNetClass() const
Function GetNetClass returns the NETCLASS for this item.
const wxPoint & GetStart() const
Definition: class_track.h:123
int m_TrackMinWidth
track min value for width ((min copper size value
int m_ViasMinSize
vias (not micro vias) min diameter
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
static bool checkMarginToCircle(wxPoint aCentre, int aRadius, int aLength)
Helper function checkMarginToCircle Check the distance from a point to a segment. ...
#define DRCE_TRACK_NEAR_PAD
pad too close to track
Definition: drc_stuff.h:47
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
int m_xcliphi
Definition: drc_stuff.h:207
int m_MicroViasMinSize
micro vias (not vias) min diameter
unsigned GetPadCount() const
Function GetPadCount.
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
int GetNetCode() const
Function GetNetCode.
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
#define DRCE_TOO_SMALL_TRACK_WIDTH
Too small track width.
Definition: drc_stuff.h:70
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:192
TRACK * Next() const
Definition: class_track.h:100
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
int GetWidth() const
Definition: class_track.h:117
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
#define DRCE_ENDS_PROBLEM3
track ends are too close
Definition: drc_stuff.h:59
#define DRCE_TRACK_ENDS4
2 parallel track segments too close: fine end point test
Definition: drc_stuff.h:54
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:375
#define DRCE_VIA_NEAR_VIA
via too close to via
Definition: drc_stuff.h:49
wxPoint ShapePos() const
Definition: class_pad.cpp:500
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
bool m_MicroViasAllowed
true to allow micro vias
int m_MicroViasMinDrill
micro vias (not vias) min drill diameter
#define DRCE_TRACK_ENDS2
2 parallel track segments too close: fine start point test
Definition: drc_stuff.h:52
const wxPoint GetPosition() const override
Definition: class_pad.h:220
#define DRCE_TRACK_ENDS3
2 parallel track segments too close: fine end point test
Definition: drc_stuff.h:53
#define DRCE_ENDS_PROBLEM4
track ends are too close
Definition: drc_stuff.h:60
int m_xcliplo
Definition: drc_stuff.h:205
#define DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR
micro via's layer pair incorrect (layers must be adjacent)
Definition: drc_stuff.h:64
double m_segmAngle
Definition: drc_stuff.h:199
#define DRCE_TRACK_NEAR_THROUGH_HOLE
thru hole is too close to track
Definition: drc_stuff.h:46
#define DRCE_VIA_HOLE_BIGGER
via's hole is bigger than its diameter
Definition: drc_stuff.h:63
#define DRCE_BURIED_VIA_NOT_ALLOWED
buried vias are not allowed
Definition: drc_stuff.h:92
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
#define DRCE_TOO_SMALL_VIA_DRILL
Too small via drill.
Definition: drc_stuff.h:73
#define DRCE_TOO_SMALL_VIA
Too small via size.
Definition: drc_stuff.h:71
bool DRC::doTrackKeepoutDrc ( TRACK aRefSeg)
private

Function doTrackKeepoutDrc tests the current segment or via.

Parameters
aRefSegThe segment to test
Returns
bool - true if no poblems, else false and m_currentMarker is filled in with the problem information.

Definition at line 961 of file drc.cpp.

References ZONE_CONTAINER::CommonLayerExists(), SHAPE_POLY_SET::Distance(), DRCE_TRACK_INSIDE_KEEPOUT, DRCE_VIA_INSIDE_KEEPOUT, fillMarker(), BOARD::GetArea(), BOARD::GetAreaCount(), ZONE_CONTAINER::GetDoNotAllowTracks(), ZONE_CONTAINER::GetDoNotAllowVias(), TRACK::GetEnd(), ZONE_CONTAINER::GetIsKeepout(), BOARD_ITEM::GetLayer(), BOARD_ITEM::GetLayerSet(), TRACK::GetPosition(), TRACK::GetStart(), TRACK::GetWidth(), ZONE_CONTAINER::IsOnLayer(), m_currentMarker, m_pcb, ZONE_CONTAINER::Outline(), PCB_TRACE_T, PCB_VIA_T, and EDA_ITEM::Type().

Referenced by Drc(), and DrcBlind().

962 {
963  // Test keepout areas for vias, tracks and pads inside keepout areas
964  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
965  {
966  ZONE_CONTAINER* area = m_pcb->GetArea( ii );
967 
968  if( !area->GetIsKeepout() )
969  continue;
970 
971  if( aRefSeg->Type() == PCB_TRACE_T )
972  {
973  if( ! area->GetDoNotAllowTracks() )
974  continue;
975 
976  if( !area->IsOnLayer( aRefSeg->GetLayer() ) )
977  continue;
978 
979  if( area->Outline()->Distance( SEG( aRefSeg->GetStart(), aRefSeg->GetEnd() ),
980  aRefSeg->GetWidth() ) == 0 )
981  {
982  m_currentMarker = fillMarker( aRefSeg, NULL,
984  return false;
985  }
986  }
987  else if( aRefSeg->Type() == PCB_VIA_T )
988  {
989  if( ! area->GetDoNotAllowVias() )
990  continue;
991 
992  auto viaLayers = aRefSeg->GetLayerSet();
993 
994  if( !area->CommonLayerExists( viaLayers ) )
995  continue;
996 
997  if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 )
998  {
999  m_currentMarker = fillMarker( aRefSeg, NULL,
1001  return false;
1002  }
1003  }
1004  }
1005 
1006  return true;
1007 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:225
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
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:191
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...
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
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:262
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:236
const wxPoint & GetEnd() const
Definition: class_track.h:120
#define DRCE_TRACK_INSIDE_KEEPOUT
Track in inside a keepout area.
Definition: drc_stuff.h:82
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
BOARD * m_pcb
Definition: drc_stuff.h:211
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:602
#define DRCE_VIA_INSIDE_KEEPOUT
Via in inside a keepout area.
Definition: drc_stuff.h:81
const wxPoint GetPosition() const override
Definition: class_track.h:114
const wxPoint & GetStart() const
Definition: class_track.h:123
virtual LSET GetLayerSet() const
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
Definition: seg.h:36
bool GetDoNotAllowTracks() const
Definition: class_zone.h:605
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
bool GetDoNotAllowVias() const
Definition: class_zone.h:604
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...
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
int DRC::Drc ( TRACK aRefSeg,
TRACK aList 
)

Function Drc tests the current segment and returns the result and displays the error in the status panel only if one exists.

Parameters
aRefSegThe current segment to test.
aListThe track list to test (usually m_Pcb->m_Track)
Returns
int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK

Definition at line 158 of file drc.cpp.

References BAD_DRC, doTrackDrc(), doTrackKeepoutDrc(), m_currentMarker, m_pcbEditorFrame, OK_DRC, EDA_DRAW_FRAME::SetMsgPanel(), and updatePointers().

Referenced by PCB_EDIT_FRAME::Add45DegreeSegment(), PCB_EDIT_FRAME::Begin_Route(), PCB_EDIT_FRAME::Begin_Zone(), PCB_EDIT_FRAME::End_Route(), PCB_EDIT_FRAME::End_Zone(), PCB_EDIT_FRAME::Other_Layer_Route(), PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment(), and PCB_EDIT_FRAME::SetTrackSegmentWidth().

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 }
#define OK_DRC
Definition: drc_stuff.h:35
bool doTrackKeepoutDrc(TRACK *aRefSeg)
Function doTrackKeepoutDrc tests the current segment or via.
Definition: drc.cpp:961
#define BAD_DRC
Definition: drc_stuff.h:36
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:793
void updatePointers()
Function updatePointers is a private helper function used to update needed pointers from the one poin...
Definition: drc.cpp:490
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc_stuff.h:210
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
bool doTrackDrc(TRACK *aRefSeg, TRACK *aStart, bool doPads=true)
Function DoTrackDrc tests the current segment.
int DRC::Drc ( ZONE_CONTAINER aArea,
int  aCornerIndex 
)

Function Drc tests the outline segment starting at CornerIndex and returns the result and displays the error in the status panel only if one exists.

Test Edge inside other areas Test Edge too close other areas

Parameters
aAreaThe areaparent which contains the corner.
aCornerIndexThe starting point of the segment to test.
Returns
int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK

Definition at line 344 of file drc.cpp.

References BAD_DRC, doEdgeZoneDrc(), m_currentMarker, m_pcbEditorFrame, OK_DRC, EDA_DRAW_FRAME::SetMsgPanel(), and updatePointers().

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 }
#define OK_DRC
Definition: drc_stuff.h:35
#define BAD_DRC
Definition: drc_stuff.h:36
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:793
void updatePointers()
Function updatePointers is a private helper function used to update needed pointers from the one poin...
Definition: drc.cpp:490
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc_stuff.h:210
bool doEdgeZoneDrc(ZONE_CONTAINER *aArea, int aCornerIndex)
Function doEdgeZoneDrc tests a segment in ZONE_CONTAINER * aArea: Test Edge inside other areas Test E...
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
int DRC::DrcBlind ( TRACK aRefSeg,
TRACK aList 
)
inline

Function DrcBlind tests the current segment and returns the result.

Any error is not displayed in the status panel.

Parameters
aRefSegThe current segment to test.
aListThe track list to test (usually m_Pcb->m_Track)
Returns
int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK

Definition at line 457 of file drc_stuff.h.

References BAD_DRC, doTrackDrc(), doTrackKeepoutDrc(), OK_DRC, and updatePointers().

458  {
459  updatePointers();
460 
461  if( ! doTrackDrc( aRefSeg, aList ) )
462  return BAD_DRC;
463 
464  return doTrackKeepoutDrc( aRefSeg ) ? OK_DRC : BAD_DRC;
465  }
#define OK_DRC
Definition: drc_stuff.h:35
bool doTrackKeepoutDrc(TRACK *aRefSeg)
Function doTrackKeepoutDrc tests the current segment or via.
Definition: drc.cpp:961
#define BAD_DRC
Definition: drc_stuff.h:36
void updatePointers()
Function updatePointers is a private helper function used to update needed pointers from the one poin...
Definition: drc.cpp:490
bool doTrackDrc(TRACK *aRefSeg, TRACK *aStart, bool doPads=true)
Function DoTrackDrc tests the current segment.
MARKER_PCB * DRC::fillMarker ( const TRACK aTrack,
BOARD_ITEM aItem,
int  aErrorCode,
MARKER_PCB fillMe 
)
private

Function fillMarker optionally creates a marker and fills it in with information, but does not add it to the BOARD.

Use this to report any kind of DRC problem, or unconnected pad problem.

Parameters
aTrackThe reference track.
aItemAnother item on the BOARD, such as a VIA, SEGZONE, or TRACK.
aErrorCodeA categorizing identifier for the particular type of error that is being reported.
fillMeA MARKER_PCB* which is to be filled in, or NULL if one is to first be allocated, then filled.

Definition at line 49 of file drc_marker_functions.cpp.

References TRACK::GetEnd(), GetLineLength(), TRACK::GetPosition(), TRACK::GetSelectMenuText(), EDA_ITEM::GetSelectMenuText(), TRACK::GetStart(), PCB_PAD_T, PCB_TEXT_T, PCB_TRACE_T, PCB_VIA_T, MARKER_BASE::SetData(), MARKER_PCB::SetItem(), and EDA_ITEM::Type().

Referenced by doEdgeZoneDrc(), doFootprintOverlappingDrc(), doNetClass(), doPadToPadsDrc(), doTrackDrc(), doTrackKeepoutDrc(), testKeepoutAreas(), testTexts(), and testZones().

51 {
52  wxString textA = aTrack->GetSelectMenuText();
53  wxString textB;
54 
55  wxPoint position;
56  wxPoint posB;
57 
58  if( aItem ) // aItem might be NULL
59  {
60  textB = aItem->GetSelectMenuText();
61 
62  if( aItem->Type() == PCB_PAD_T )
63  {
64  posB = position = ((D_PAD*)aItem)->GetPosition();
65  }
66  else if( aItem->Type() == PCB_VIA_T )
67  {
68  posB = position = ((VIA*)aItem)->GetPosition();
69  }
70  else if( aItem->Type() == PCB_TRACE_T )
71  {
72  TRACK* track = (TRACK*) aItem;
73 
74  posB = track->GetPosition();
75 
76  wxPoint endPos = track->GetEnd();
77 
78  // either of aItem's start or end will be used for the marker position
79  // first assume start, then switch at end if needed. decision made on
80  // distance from end of aTrack.
81  position = track->GetStart();
82 
83  double dToEnd = GetLineLength( endPos, aTrack->GetEnd() );
84  double dToStart = GetLineLength( position, aTrack->GetEnd() );
85 
86  if( dToEnd < dToStart )
87  position = endPos;
88  }
89  else if( aItem->Type() == PCB_TEXT_T )
90  {
91  position = aTrack->GetPosition();
92  posB = ((TEXTE_PCB*) aItem)->GetPosition();
93  }
94  }
95  else
96  position = aTrack->GetPosition();
97 
98  if( fillMe )
99  {
100  if( aItem )
101  fillMe->SetData( aErrorCode, position,
102  textA, aTrack->GetPosition(),
103  textB, posB );
104  else
105  fillMe->SetData( aErrorCode, position,
106  textA, aTrack->GetPosition() );
107  }
108  else
109  {
110  if( aItem )
111  {
112  fillMe = new MARKER_PCB( aErrorCode, position,
113  textA, aTrack->GetPosition(),
114  textB, posB );
115  fillMe->SetItem( aItem );
116  }
117  else
118  {
119  fillMe = new MARKER_PCB( aErrorCode, position,
120  textA, aTrack->GetPosition() );
121  }
122  }
123 
124  return fillMe;
125 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:225
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Function GetLineLength returns the length of a line segment defined by aPointA and aPointB...
Definition: trigo.h:191
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
virtual wxString GetSelectMenuText() const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
const wxPoint & GetEnd() const
Definition: class_track.h:120
void SetData(int aErrorCode, const wxPoint &aMarkerPos, const wxString &aText, const wxPoint &aPos, const wxString &bText, const wxPoint &bPos)
Function SetData fills in all the reportable data associated with a MARKER.
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void SetItem(const BOARD_ITEM *aItem)
const wxPoint GetPosition() const override
Definition: class_track.h:114
const wxPoint & GetStart() const
Definition: class_track.h:123
virtual wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
MARKER_PCB * DRC::fillMarker ( D_PAD aPad,
BOARD_ITEM aItem,
int  aErrorCode,
MARKER_PCB fillMe 
)
private

Definition at line 128 of file drc_marker_functions.cpp.

References D_PAD::GetPosition(), EDA_ITEM::GetSelectMenuText(), D_PAD::GetSelectMenuText(), PCB_PAD_T, PCB_TEXT_T, MARKER_BASE::SetData(), MARKER_PCB::SetItem(), and EDA_ITEM::Type().

129 {
130  wxString textA = aPad->GetSelectMenuText();
131  wxString textB;
132 
133  wxPoint posA = aPad->GetPosition();
134  wxPoint posB;
135 
136  if( aItem )
137  {
138  textB = aItem->GetSelectMenuText();
139 
140  switch( aItem->Type() )
141  {
142  case PCB_PAD_T:
143  posB = ((D_PAD*)aItem)->GetPosition();
144  break;
145 
146  case PCB_TEXT_T:
147  posB = ((TEXTE_PCB*)aItem)->GetPosition();
148  break;
149 
150  default:
151  wxLogDebug( wxT("fillMarker: unsupported item") );
152  break;
153  }
154  }
155 
156  if( fillMe )
157  {
158  fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB );
159  }
160  else
161  {
162  fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA, textB, posB );
163  fillMe->SetItem( aPad ); // TODO it has to be checked
164  }
165 
166  return fillMe;
167 }
KICAD_T Type() const
Function Type()
Definition: base_struct.h:225
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: class_pad.cpp:1179
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
virtual wxString GetSelectMenuText() const
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
void SetData(int aErrorCode, const wxPoint &aMarkerPos, const wxString &aText, const wxPoint &aPos, const wxString &bText, const wxPoint &bPos)
Function SetData fills in all the reportable data associated with a MARKER.
void SetItem(const BOARD_ITEM *aItem)
const wxPoint GetPosition() const override
Definition: class_pad.h:220
MARKER_PCB * DRC::fillMarker ( ZONE_CONTAINER aArea,
int  aErrorCode,
MARKER_PCB fillMe 
)
private

Definition at line 170 of file drc_marker_functions.cpp.

References ZONE_CONTAINER::GetPosition(), ZONE_CONTAINER::GetSelectMenuText(), MARKER_BASE::SetData(), and MARKER_PCB::SetItem().

171 {
172  wxString textA = aArea->GetSelectMenuText();
173 
174  wxPoint posA = aArea->GetPosition();
175 
176  if( fillMe )
177  {
178  fillMe->SetData( aErrorCode, posA, textA, posA );
179  }
180  else
181  {
182  fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
183  fillMe->SetItem( aArea );
184  }
185 
186  return fillMe;
187 }
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
const wxPoint GetPosition() const override
Function GetPosition.
Definition: class_zone.cpp:166
void SetData(int aErrorCode, const wxPoint &aMarkerPos, const wxString &aText, const wxPoint &aPos, const wxString &bText, const wxPoint &bPos)
Function SetData fills in all the reportable data associated with a MARKER.
void SetItem(const BOARD_ITEM *aItem)
MARKER_PCB * DRC::fillMarker ( const wxPoint aPos,
int  aErrorCode,
const wxString &  aMessage,
MARKER_PCB fillMe 
)
private

Definition at line 228 of file drc_marker_functions.cpp.

References MARKER_BASE::SetData().

229 {
230  wxPoint posA = aPos;
231 
232  if( fillMe )
233  fillMe->SetData( aErrorCode, posA, aMessage, posA );
234  else
235  fillMe = new MARKER_PCB( aErrorCode, posA, aMessage, posA );
236 
237  return fillMe;
238 }
void SetData(int aErrorCode, const wxPoint &aMarkerPos, const wxString &aText, const wxPoint &aPos, const wxString &bText, const wxPoint &bPos)
Function SetData fills in all the reportable data associated with a MARKER.
MARKER_PCB * DRC::fillMarker ( const ZONE_CONTAINER aArea,
const wxPoint aPos,
int  aErrorCode,
MARKER_PCB fillMe 
)
private

Function fillMarker optionally creates a marker and fills it in with information, but does not add it to the BOARD.

Use this to report any kind of DRC problem, or unconnected pad problem.

Parameters
aAreaThe zone to test
aPosposition of error
aErrorCodeType of error
fillMeA MARKER_PCB* which is to be filled in, or NULL if one is to first be allocated, then filled.

Definition at line 190 of file drc_marker_functions.cpp.

References ZONE_CONTAINER::GetSelectMenuText(), MARKER_BASE::SetData(), and MARKER_PCB::SetItem().

194 {
195  wxString textA = aArea->GetSelectMenuText();
196 
197  wxPoint posA = aPos;
198 
199  if( fillMe )
200  {
201  fillMe->SetData( aErrorCode, posA, textA, posA );
202  }
203  else
204  {
205  fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA );
206  fillMe->SetItem( aArea );
207  }
208 
209  return fillMe;
210 }
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
void SetData(int aErrorCode, const wxPoint &aMarkerPos, const wxString &aText, const wxPoint &aPos, const wxString &bText, const wxPoint &bPos)
Function SetData fills in all the reportable data associated with a MARKER.
void SetItem(const BOARD_ITEM *aItem)
MARKER_PCB * DRC::fillMarker ( int  aErrorCode,
const wxString &  aMessage,
MARKER_PCB fillMe 
)
private

Function fillMarker fills a MARKER which will report on a generic problem with the board which is not geographically locatable.

Definition at line 213 of file drc_marker_functions.cpp.

References MARKER_BASE::SetData(), and MARKER_BASE::SetShowNoCoordinate().

214 {
215  wxPoint posA; // not displayed
216 
217  if( fillMe )
218  fillMe->SetData( aErrorCode, posA, aMessage, posA );
219  else
220  fillMe = new MARKER_PCB( aErrorCode, posA, aMessage, posA );
221 
222  fillMe->SetShowNoCoordinate();
223 
224  return fillMe;
225 }
void SetShowNoCoordinate()
void SetData(int aErrorCode, const wxPoint &aMarkerPos, const wxString &aText, const wxPoint &aPos, const wxString &bText, const wxPoint &bPos)
Function SetData fills in all the reportable data associated with a MARKER.
MARKER_PCB* DRC::GetCurrentMarker ( )
inline
Returns
a pointer to the current marker (last created marker

Definition at line 549 of file drc_stuff.h.

References m_currentMarker.

Referenced by PCB_EDIT_FRAME::Other_Layer_Route().

550  {
551  return m_currentMarker;
552  }
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
void DRC::ListUnconnectedPads ( )

Function ListUnconnectedPad gathers a list of all the unconnected pads and shows them in the dialog, and optionally prints a report of such.

Definition at line 481 of file drc.cpp.

References testUnconnected(), and updatePointers().

Referenced by DIALOG_DRC_CONTROL::OnListUnconnectedClick().

482 {
483  testUnconnected();
484 
485  // update the m_drcDialog listboxes
486  updatePointers();
487 }
void updatePointers()
Function updatePointers is a private helper function used to update needed pointers from the one poin...
Definition: drc.cpp:490
void testUnconnected()
Definition: drc.cpp:715
void DRC::RunTests ( wxTextCtrl *  aMessages = NULL)

Function RunTests will actually run all the tests specified with a previous call to SetSettings()

Parameters
aMessages= a wxTextControl where to display some activity messages. Can be NULL

Definition at line 359 of file drc.cpp.

References doFootprintOverlappingDrc(), PCB_EDIT_FRAME::Fill_All_Zones(), PCB_BASE_FRAME::GetBoard(), m_doFootprintOverlapping, m_doKeepoutTest, m_doNoCourtyardDefined, m_doPad2PadTest, m_doUnconnectedTest, m_pcb, m_pcbEditorFrame, testKeepoutAreas(), testNetClasses(), testPad2Pad(), testTexts(), testTracks(), testUnconnected(), testZones(), and updatePointers().

Referenced by DIALOG_DRC_CONTROL::OnStartdrcClick().

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  // caller (a wxTopLevelFrame) is the wxDialog or the Pcb Editor frame that call DRC:
412  wxWindow* caller = aMessages ? aMessages->GetParent() : m_pcbEditorFrame;
413  m_pcbEditorFrame->Fill_All_Zones( caller );
414 
415  // test zone clearances to other zones
416  if( aMessages )
417  {
418  aMessages->AppendText( _( "Test zones...\n" ) );
419  wxSafeYield();
420  }
421 
422  testZones();
423 
424  // find and gather unconnected pads.
425  if( m_doUnconnectedTest )
426  {
427  if( aMessages )
428  {
429  aMessages->AppendText( _( "Unconnected pads...\n" ) );
430  aMessages->Refresh();
431  }
432 
433  testUnconnected();
434  }
435 
436  // find and gather vias, tracks, pads inside keepout areas.
437  if( m_doKeepoutTest )
438  {
439  if( aMessages )
440  {
441  aMessages->AppendText( _( "Keepout areas ...\n" ) );
442  aMessages->Refresh();
443  }
444 
446  }
447 
448  // find and gather vias, tracks, pads inside text boxes.
449  if( aMessages )
450  {
451  aMessages->AppendText( _( "Test texts...\n" ) );
452  wxSafeYield();
453  }
454 
455  testTexts();
456 
457  // find overlaping courtyard ares.
459  {
460  if( aMessages )
461  {
462  aMessages->AppendText( _( "Courtyard areas...\n" ) );
463  aMessages->Refresh();
464  }
465 
467  }
468 
469  // update the m_drcDialog listboxes
470  updatePointers();
471 
472  if( aMessages )
473  {
474  // no newline on this one because it is last, don't want the window
475  // to unnecessarily scroll.
476  aMessages->AppendText( _( "Finished" ) );
477  }
478 }
bool m_doNoCourtyardDefined
Definition: drc_stuff.h:178
void testKeepoutAreas()
Definition: drc.cpp:783
BOARD * GetBoard() const
void testTexts()
Definition: drc.cpp:837
BOARD * m_pcb
Definition: drc_stuff.h:211
bool m_doFootprintOverlapping
Definition: drc_stuff.h:177
bool m_doKeepoutTest
Definition: drc_stuff.h:175
void testZones()
Definition: drc.cpp:745
void updatePointers()
Function updatePointers is a private helper function used to update needed pointers from the one poin...
Definition: drc.cpp:490
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc_stuff.h:210
bool m_doPad2PadTest
Definition: drc_stuff.h:172
void testPad2Pad()
Definition: drc.cpp:620
bool doFootprintOverlappingDrc()
Function doFootprintOverlappingDrc tests for footprint courtyard overlaps.
Definition: drc.cpp:1144
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:597
void testTracks(wxWindow *aActiveWindow, bool aShowProgressBar)
Function testTracks performs the DRC on all tracks.
Definition: drc.cpp:659
int Fill_All_Zones(wxWindow *aActiveWindow)
Function Fill_All_Zones Fill all zones on the board The old fillings are removed. ...
void testUnconnected()
Definition: drc.cpp:715
bool m_doUnconnectedTest
Definition: drc_stuff.h:173
void DRC::SetSettings ( bool  aPad2PadTest,
bool  aUnconnectedTest,
bool  aZonesTest,
bool  aKeepoutTest,
bool  aCourtyardTest,
bool  aCourtyardMissingTest,
const wxString &  aReportName,
bool  aSaveReport 
)
inline

Function SetSettings saves all the UI or test settings and may be called before running the tests.

Parameters
aPad2PadTestTells whether to test pad to pad distances.
aUnconnectedTestTells whether to list unconnected pads.
aZonesTestTells whether to test zones.
aKeepoutTestTells whether to test keepout areas.
aCourtyardTestTells whether to test footprint courtyard overlap.
aCourtyardMissingTestTells whether to test missing courtyard definition in footprint.
aReportNameA string telling the disk file report name entered.
aSaveReportA boolean telling whether to generate disk file report.

Definition at line 515 of file drc_stuff.h.

Referenced by DIALOG_DRC_CONTROL::OnListUnconnectedClick(), and DIALOG_DRC_CONTROL::OnStartdrcClick().

519  {
520  m_doPad2PadTest = aPad2PadTest;
521  m_doUnconnectedTest = aUnconnectedTest;
522  m_doZonesTest = aZonesTest;
523  m_doKeepoutTest = aKeepoutTest;
524  m_rptFilename = aReportName;
525  m_doCreateRptFile = aSaveReport;
526  m_doFootprintOverlapping = aCourtyardTest;
527  m_doNoCourtyardDefined = aCourtyardMissingTest;
528  }
bool m_doNoCourtyardDefined
Definition: drc_stuff.h:178
bool m_doCreateRptFile
Definition: drc_stuff.h:176
bool m_doFootprintOverlapping
Definition: drc_stuff.h:177
bool m_doKeepoutTest
Definition: drc_stuff.h:175
bool m_doZonesTest
Definition: drc_stuff.h:174
bool m_doPad2PadTest
Definition: drc_stuff.h:172
wxString m_rptFilename
Definition: drc_stuff.h:180
bool m_doUnconnectedTest
Definition: drc_stuff.h:173
void DRC::ShowDRCDialog ( wxWindow *  aParent = NULL)

Function ShowDRCDialog opens a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and creates the MARKERS.

The dialog is only created if it is not already in existence.

Parameters
aParentis the parent window for wxWidgets. Usually the PCB editor frame but can be an other dialog if aParent == NULL (default), the parent will be the PCB editor frame and the dialog will be not modal (just float on parent if aParent is specified, the dialog will be modal. The modal mode is mandatory if the dialog is created from an other dialog, not from the PCB editor frame

Definition at line 59 of file drc.cpp.

References DIALOG_DRC_CONTROL, EDA_DRAW_FRAME::GetToolManager(), m_doCreateRptFile, m_drcDialog, m_pcbEditorFrame, m_rptFilename, TOOL_MANAGER::RunAction(), PCB_ACTIONS::selectionClear, DIALOG_DRC_CONTROL::SetRptSettings(), DIALOG_SHIM::Show(), and updatePointers().

Referenced by DIALOG_PLOT::onRunDRC(), and PCB_EDIT_FRAME::Process_Special_Functions().

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 }
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
bool m_doCreateRptFile
Definition: drc_stuff.h:176
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc_stuff.h:212
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
void updatePointers()
Function updatePointers is a private helper function used to update needed pointers from the one poin...
Definition: drc.cpp:490
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc_stuff.h:210
bool Show(bool show) override
friend class DIALOG_DRC_CONTROL
Definition: drc_stuff.h:166
TOOL_MANAGER * GetToolManager() const
Function GetToolManager returns the tool manager instance, if any.
Definition: draw_frame.h:886
wxString m_rptFilename
Definition: drc_stuff.h:180
void SetRptSettings(bool aEnable, const wxString &aFileName)
Enable/disable the report file creation.
Definition: dialog_drc.cpp:174
void DRC::testKeepoutAreas ( )
private

Definition at line 783 of file drc.cpp.

References addMarkerToPcb(), ZONE_CONTAINER::CommonLayerExists(), SHAPE_POLY_SET::Distance(), DRCE_TRACK_INSIDE_KEEPOUT, DRCE_VIA_INSIDE_KEEPOUT, fillMarker(), BOARD::GetArea(), BOARD::GetAreaCount(), ZONE_CONTAINER::GetDoNotAllowTracks(), ZONE_CONTAINER::GetDoNotAllowVias(), ZONE_CONTAINER::GetIsKeepout(), BOARD_ITEM::GetLayerSet(), ZONE_CONTAINER::IsOnLayer(), m_currentMarker, m_pcb, BOARD::m_Track, TRACK::Next(), ZONE_CONTAINER::Outline(), PCB_TRACE_T, and PCB_VIA_T.

Referenced by RunTests().

784 {
785  // Test keepout areas for vias, tracks and pads inside keepout areas
786  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
787  {
788  ZONE_CONTAINER* area = m_pcb->GetArea( ii );
789 
790  if( !area->GetIsKeepout() )
791  {
792  continue;
793  }
794 
795  for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() )
796  {
797  if( segm->Type() == PCB_TRACE_T )
798  {
799  if( ! area->GetDoNotAllowTracks() )
800  continue;
801 
802  // Ignore if the keepout zone is not on the same layer
803  if( !area->IsOnLayer( segm->GetLayer() ) )
804  continue;
805 
806  if( area->Outline()->Distance( SEG( segm->GetStart(), segm->GetEnd() ),
807  segm->GetWidth() ) == 0 )
808  {
809  addMarkerToPcb( fillMarker( segm, NULL,
811  m_currentMarker = nullptr;
812  }
813  }
814  else if( segm->Type() == PCB_VIA_T )
815  {
816  if( ! area->GetDoNotAllowVias() )
817  continue;
818 
819  auto viaLayers = segm->GetLayerSet();
820 
821  if( !area->CommonLayerExists( viaLayers ) )
822  continue;
823 
824  if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 )
825  {
826  addMarkerToPcb( fillMarker( segm, NULL,
828  m_currentMarker = nullptr;
829  }
830  }
831  }
832  // Test pads: TODO
833  }
834 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
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:191
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...
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:262
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:236
#define DRCE_TRACK_INSIDE_KEEPOUT
Track in inside a keepout area.
Definition: drc_stuff.h:82
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
BOARD * m_pcb
Definition: drc_stuff.h:211
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:602
void addMarkerToPcb(MARKER_PCB *aMarker)
Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism.
Definition: drc.cpp:94
#define DRCE_VIA_INSIDE_KEEPOUT
Via in inside a keepout area.
Definition: drc_stuff.h:81
virtual LSET GetLayerSet() const
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
Definition: seg.h:36
bool GetDoNotAllowTracks() const
Definition: class_zone.h:605
TRACK * Next() const
Definition: class_track.h:100
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
bool GetDoNotAllowVias() const
Definition: class_zone.h:604
int Distance(VECTOR2I aPoint)
Function DistanceToPolygon computes the minimum distance between aPoint and all the polygons in the s...
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
DLIST< TRACK > m_Track
Definition: class_board.h:246
bool DRC::testNetClasses ( )
private

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.

This is necessary because the actual DRC checks are run against the NETCLASS limits, so in order enforce global limits, we first check the NETCLASSes against the global limits.

Returns
bool - true if succes, else false but only after reporting all NETCLASS violations.

Definition at line 597 of file drc.cpp.

References NETCLASSES::begin(), doNetClass(), NETCLASSES::end(), NETCLASSES::GetDefault(), BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::m_NetClasses, and m_pcb.

Referenced by RunTests().

598 {
599  bool ret = true;
600 
602 
603  wxString msg; // construct this only once here, not in a loop, since somewhat expensive.
604 
605  if( !doNetClass( netclasses.GetDefault(), msg ) )
606  ret = false;
607 
608  for( NETCLASSES::const_iterator i = netclasses.begin(); i != netclasses.end(); ++i )
609  {
610  NETCLASSPTR nc = i->second;
611 
612  if( !doNetClass( nc, msg ) )
613  ret = false;
614  }
615 
616  return ret;
617 }
bool doNetClass(const std::shared_ptr< NETCLASS > &aNetClass, wxString &msg)
Definition: drc.cpp:505
iterator end()
NETCLASS_MAP::const_iterator const_iterator
BOARD * m_pcb
Definition: drc_stuff.h:211
iterator begin()
Class NETCLASSES is a container for NETCLASS instances.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:532
NETCLASSPTR GetDefault() const
Function GetDefault.
NETCLASSES m_NetClasses
List of current netclasses. There is always the default netclass.
void DRC::testPad2Pad ( )
private

Definition at line 620 of file drc.cpp.

References addMarkerToPcb(), doPadToPadsDrc(), D_PAD::GetBoundingRadius(), D_PAD::GetClearance(), D_PAD::GetPosition(), BOARD::GetSortedPadListByXthenYCoord(), m_currentMarker, m_pcb, and wxPoint::x.

Referenced by RunTests().

621 {
622  std::vector<D_PAD*> sortedPads;
623 
624  m_pcb->GetSortedPadListByXthenYCoord( sortedPads );
625 
626  // find the max size of the pads (used to stop the test)
627  int max_size = 0;
628 
629  for( unsigned i = 0; i < sortedPads.size(); ++i )
630  {
631  D_PAD* pad = sortedPads[i];
632 
633  // GetBoundingRadius() is the radius of the minimum sized circle fully containing the pad
634  int radius = pad->GetBoundingRadius();
635  if( radius > max_size )
636  max_size = radius;
637  }
638 
639  // Test the pads
640  D_PAD** listEnd = &sortedPads[ sortedPads.size() ];
641 
642  for( unsigned i = 0; i< sortedPads.size(); ++i )
643  {
644  D_PAD* pad = sortedPads[i];
645 
646  int x_limit = max_size + pad->GetClearance() +
647  pad->GetBoundingRadius() + pad->GetPosition().x;
648 
649  if( !doPadToPadsDrc( pad, &sortedPads[i], listEnd, x_limit ) )
650  {
651  wxASSERT( m_currentMarker );
653  m_currentMarker = nullptr;
654  }
655  }
656 }
void GetSortedPadListByXthenYCoord(std::vector< D_PAD * > &aVector, int aNetCode=-1)
Function GetSortedPadListByXthenYCoord first empties then fills the vector with all pads and sorts th...
BOARD * m_pcb
Definition: drc_stuff.h:211
void addMarkerToPcb(MARKER_PCB *aMarker)
Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism.
Definition: drc.cpp:94
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:586
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:1010
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_pad.cpp:546
const wxPoint GetPosition() const override
Definition: class_pad.h:220
void DRC::testTexts ( )
private

Definition at line 837 of file drc.cpp.

References addMarkerToPcb(), ArcTangente(), checkClearanceSegmToPad(), delta, dist, BOARD::Drawings(), DRCE_PAD_INSIDE_TEXT, DRCE_TRACK_INSIDE_TEXT, DRCE_VIA_INSIDE_TEXT, fillMarker(), D_PAD::GetClearance(), BOARD::GetPads(), EDA_TEXT::GetThickness(), IsCopperLayer(), D_PAD::IsOnLayer(), m_currentMarker, m_padToTestPos, m_pcb, m_segmAngle, m_segmEnd, m_segmLength, BOARD::m_Track, TRACK::Next(), PCB_TEXT_T, PCB_TRACE_T, PCB_VIA_T, SEG::PointCloserThan(), RotatePoint(), D_PAD::ShapePos(), EDA_TEXT::TransformTextShapeToSegmentList(), wxPoint::x, and wxPoint::y.

Referenced by RunTests().

838 {
839  std::vector<wxPoint> textShape; // a buffer to store the text shape (set of segments)
840  std::vector<D_PAD*> padList = m_pcb->GetPads();
841 
842  // Test text areas for vias, tracks and pads inside text areas
843  for( auto item : m_pcb->Drawings() )
844  {
845  // Drc test only items on copper layers
846  if( ! IsCopperLayer( item->GetLayer() ) )
847  continue;
848 
849  // only texts on copper layers are tested
850  if( item->Type() != PCB_TEXT_T )
851  continue;
852 
853  textShape.clear();
854 
855  // So far the bounding box makes up the text-area
856  TEXTE_PCB* text = (TEXTE_PCB*) item;
857  text->TransformTextShapeToSegmentList( textShape );
858 
859  if( textShape.size() == 0 ) // Should not happen (empty text?)
860  continue;
861 
862  for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
863  {
864  if( ! track->IsOnLayer( item->GetLayer() ) )
865  continue;
866 
867  // Test the distance between each segment and the current track/via
868  int min_dist = ( track->GetWidth() + text->GetThickness() ) /2 +
869  track->GetClearance(NULL);
870 
871  if( track->Type() == PCB_TRACE_T )
872  {
873  SEG segref( track->GetStart(), track->GetEnd() );
874 
875  // Error condition: Distance between text segment and track segment is
876  // smaller than the clearance of the segment
877  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
878  {
879  SEG segtest( textShape[jj], textShape[jj+1] );
880  int dist = segref.Distance( segtest );
881 
882  if( dist < min_dist )
883  {
884  addMarkerToPcb( fillMarker( track, text,
886  m_currentMarker ) );
887  m_currentMarker = nullptr;
888  break;
889  }
890  }
891  }
892  else if( track->Type() == PCB_VIA_T )
893  {
894  // Error condition: Distance between text segment and via is
895  // smaller than the clearance of the via
896  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
897  {
898  SEG segtest( textShape[jj], textShape[jj+1] );
899 
900  if( segtest.PointCloserThan( track->GetPosition(), min_dist ) )
901  {
902  addMarkerToPcb( fillMarker( track, text,
904  m_currentMarker = nullptr;
905  break;
906  }
907  }
908  }
909  }
910 
911  // Test pads
912  for( unsigned ii = 0; ii < padList.size(); ii++ )
913  {
914  D_PAD* pad = padList[ii];
915 
916  if( ! pad->IsOnLayer( item->GetLayer() ) )
917  continue;
918 
919  wxPoint shape_pos = pad->ShapePos();
920 
921  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
922  {
923  /* In order to make some calculations more easier or faster,
924  * pads and tracks coordinates will be made relative
925  * to the segment origin
926  */
927  wxPoint origin = textShape[jj]; // origin will be the origin of other coordinates
928  m_segmEnd = textShape[jj+1] - origin;
930  m_segmAngle = 0;
931 
932  // for a non horizontal or vertical segment Compute the segment angle
933  // in tenths of degrees and its length
934  if( delta.x || delta.y ) // delta.x == delta.y == 0 for vias
935  {
936  // Compute the segment angle in 0,1 degrees
937  m_segmAngle = ArcTangente( delta.y, delta.x );
938 
939  // Compute the segment length: we build an equivalent rotated segment,
940  // this segment is horizontal, therefore dx = length
941  RotatePoint( &delta, m_segmAngle ); // delta.x = length, delta.y = 0
942  }
943 
944  m_segmLength = delta.x;
945  m_padToTestPos = shape_pos - origin;
946 
947  if( !checkClearanceSegmToPad( pad, text->GetThickness(),
948  pad->GetClearance(NULL) ) )
949  {
950  addMarkerToPcb( fillMarker( pad, text,
952  m_currentMarker = nullptr;
953  break;
954  }
955  }
956  }
957  }
958 }
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...
static const int dist[10][10]
Definition: dist.cpp:57
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
int m_segmLength
Definition: drc_stuff.h:200
#define DRCE_VIA_INSIDE_TEXT
Via in inside a text area.
Definition: drc_stuff.h:84
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
#define DRCE_PAD_INSIDE_TEXT
Pad in inside a text area.
Definition: drc_stuff.h:86
wxPoint m_padToTestPos
Definition: drc_stuff.h:191
static const int delta[8][2]
Definition: solve.cpp:112
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:152
BOARD * m_pcb
Definition: drc_stuff.h:211
#define DRCE_TRACK_INSIDE_TEXT
Track in inside a text area.
Definition: drc_stuff.h:85
void addMarkerToPcb(MARKER_PCB *aMarker)
Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism.
Definition: drc.cpp:94
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:271
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
Definition: seg.h:36
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:192
TRACK * Next() const
Definition: class_track.h:100
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
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_pad.cpp:546
wxPoint ShapePos() const
Definition: class_pad.cpp:500
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
DLIST< TRACK > m_Track
Definition: class_board.h:246
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
double m_segmAngle
Definition: drc_stuff.h:199
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:251
void DRC::testTracks ( wxWindow *  aActiveWindow,
bool  aShowProgressBar 
)
private

Function testTracks performs the DRC on all tracks.

because this test can take a while, a progress bar can be displayed

Parameters
aActiveWindow= the active window ued as parent for the progress bar
aShowProgressBar= true to show a progress bar (Note: it is shown only if there are many tracks)

Definition at line 659 of file drc.cpp.

References addMarkerToPcb(), delta, doTrackDrc(), m_currentMarker, m_pcb, BOARD::m_Track, and TRACK::Next().

Referenced by RunTests().

660 {
661  wxProgressDialog * progressDialog = NULL;
662  const int delta = 500; // This is the number of tests between 2 calls to the
663  // progress bar
664  int count = 0;
665  for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() )
666  count++;
667 
668  int deltamax = count/delta;
669 
670  if( aShowProgressBar && deltamax > 3 )
671  {
672  // Do not use wxPD_APP_MODAL style here: it is not necessary and create issues
673  // on OSX
674  progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString,
675  deltamax, aActiveWindow,
676  wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME );
677  progressDialog->Update( 0, wxEmptyString );
678  }
679 
680  int ii = 0;
681  count = 0;
682 
683  for( TRACK* segm = m_pcb->m_Track; segm; segm = segm->Next() )
684  {
685  if ( ii++ > delta )
686  {
687  ii = 0;
688  count++;
689 
690  if( progressDialog )
691  {
692  if( !progressDialog->Update( count, wxEmptyString ) )
693  break; // Aborted by user
694 #ifdef __WXMAC__
695  // Work around a dialog z-order issue on OS X
696  if( count == deltamax )
697  aActiveWindow->Raise();
698 #endif
699  }
700  }
701 
702  if( !doTrackDrc( segm, segm->Next(), true ) )
703  {
704  wxASSERT( m_currentMarker );
706  m_currentMarker = nullptr;
707  }
708  }
709 
710  if( progressDialog )
711  progressDialog->Destroy();
712 }
static const int delta[8][2]
Definition: solve.cpp:112
BOARD * m_pcb
Definition: drc_stuff.h:211
void addMarkerToPcb(MARKER_PCB *aMarker)
Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism.
Definition: drc.cpp:94
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
TRACK * Next() const
Definition: class_track.h:100
bool doTrackDrc(TRACK *aRefSeg, TRACK *aStart, bool doPads=true)
Function DoTrackDrc tests the current segment.
DLIST< TRACK > m_Track
Definition: class_board.h:246
void DRC::testUnconnected ( )
private

Definition at line 715 of file drc.cpp.

References DRCE_UNCONNECTED_ITEMS, BOARD::GetConnectivity(), m_pcb, and m_unconnected.

Referenced by ListUnconnectedPads(), and RunTests().

716 {
717 
718  auto connectivity = m_pcb->GetConnectivity();
719 
720  connectivity->Clear();
721  connectivity->Build(m_pcb); // just in case. This really needs to be reliable.
722  connectivity->RecalculateRatsnest();
723 
724  std::vector<CN_EDGE> edges;
725  connectivity->GetUnconnectedEdges( edges );
726 
727  for( const auto& edge : edges )
728  {
729  wxString t_src = edge.GetSourceNode()->Parent()->GetSelectMenuText();
730  wxString t_dst = edge.GetTargetNode()->Parent()->GetSelectMenuText();
731  auto src = edge.GetSourcePos();
732  auto dst = edge.GetTargetPos();
733 
734 
735  DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_ITEMS,
736  t_src,
737  t_dst,
738  wxPoint( src.x, src.y ), wxPoint( dst.x, dst.y ) );
739  m_unconnected.push_back( uncItem );
740 
741  }
742 }
Class DRC_ITEM is a holder for a DRC (in Pcbnew) or ERC (in Eeschema) error item. ...
#define DRCE_UNCONNECTED_ITEMS
items are unconnected
Definition: drc_stuff.h:45
BOARD * m_pcb
Definition: drc_stuff.h:211
DRC_LIST m_unconnected
list of unconnected pads, as DRC_ITEMs
Definition: drc_stuff.h:214
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:290
void DRC::testZones ( )
private

Definition at line 745 of file drc.cpp.

References addMarkerToPcb(), DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE, fillMarker(), BOARD::GetArea(), BOARD::GetAreaCount(), BOARD::GetConnectivity(), BOARD_CONNECTED_ITEM::GetNetCode(), ZONE_CONTAINER::IsOnCopperLayer(), m_currentMarker, m_pcb, and TestZoneToZoneOutline().

Referenced by RunTests().

746 {
747  // Test copper areas for valid netcodes
748  // if a netcode is < 0 the netname was not found when reading a netlist
749  // if a netcode is == 0 the netname is void, and the zone is not connected.
750  // This is allowed, but i am not sure this is a good idea
751  //
752  // In recent Pcbnew versions, the netcode is always >= 0, but an internal net name
753  // is stored, and initalized from the file or the zone properpies editor.
754  // if it differs from the net name from net code, there is a DRC issue
755  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
756  {
757  ZONE_CONTAINER* test_area = m_pcb->GetArea( ii );
758 
759  if( !test_area->IsOnCopperLayer() )
760  continue;
761 
762  int netcode = test_area->GetNetCode();
763 
764  // a netcode < 0 or > 0 and no pad in net is a error or strange
765  // perhaps a "dead" net, which happens when all pads in this net were removed
766  // Remark: a netcode < 0 should not happen (this is more a bug somewhere)
767  int pads_in_net = (test_area->GetNetCode() > 0) ?
768  m_pcb->GetConnectivity()->GetPadCount( test_area->GetNetCode() ) : 1;
769 
770  if( ( netcode < 0 ) || pads_in_net == 0 )
771  {
772  addMarkerToPcb( fillMarker( test_area,
774  m_currentMarker = nullptr;
775  }
776  }
777 
778  // Test copper areas outlines, and create markers when needed
779  TestZoneToZoneOutline( NULL, true );
780 }
#define DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE
copper area has a net but no pads in nets, which is suspicious
Definition: drc_stuff.h:67
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
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...
int TestZoneToZoneOutline(ZONE_CONTAINER *aZone, bool aCreateMarkers)
Definition: drc.cpp:182
BOARD * m_pcb
Definition: drc_stuff.h:211
void addMarkerToPcb(MARKER_PCB *aMarker)
Function addMarkerToPcb Adds a DRC marker to the PCB throught the COMMIT mechanism.
Definition: drc.cpp:94
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
int GetNetCode() const
Function GetNetCode.
MARKER_PCB * m_currentMarker
Definition: drc_stuff.h:182
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.cpp:178
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:290
int DRC::TestZoneToZoneOutline ( ZONE_CONTAINER aZone,
bool  aCreateMarkers 
)

Definition at line 182 of file drc.cpp.

References SEG::A, COMMIT::Add(), SEG::B, ZONE_CONTAINER::BuildSmoothedPoly(), SHAPE_POLY_SET::Contains(), COPPERAREA_CLOSE_TO_COPPERAREA, COPPERAREA_INSIDE_COPPERAREA, BOARD::GetArea(), BOARD::GetAreaCount(), PCB_BASE_FRAME::GetBoard(), ZONE_CONTAINER::GetClearance(), GetClearanceBetweenSegments(), ZONE_CONTAINER::GetIsKeepout(), ZONE_CONTAINER::GetLayer(), BOARD_CONNECTED_ITEM::GetNetCode(), ZONE_CONTAINER::GetPriority(), ZONE_CONTAINER::GetSelectMenuText(), ZONE_CONTAINER::IsOnCopperLayer(), SHAPE_POLY_SET::IterateSegmentsWithHoles(), SHAPE_POLY_SET::IterateWithHoles(), m_pcbEditorFrame, BOARD_COMMIT::Push(), wxPoint::x, VECTOR2< T >::x, wxPoint::y, and VECTOR2< T >::y.

Referenced by PCB_EDIT_FRAME::duplicateZone(), PCB_EDIT_FRAME::End_Move_Zone_Corner_Or_Outlines(), PCB_EDIT_FRAME::End_Zone(), PCB_EDIT_FRAME::Remove_Zone_Corner(), and testZones().

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 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Returns an iterator object, for all outlines in the set (with holes)
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:172
bool BuildSmoothedPoly(SHAPE_POLY_SET &aSmoothedPoly) const
Function GetSmoothedPoly returns a pointer to the corner-smoothed version of m_Poly if it exists...
#define COPPERAREA_CLOSE_TO_COPPERAREA
copper area outlines are too close
Definition: drc_stuff.h:66
BOARD * GetBoard() const
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 GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_zone.cpp:777
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:602
ITERATOR IterateWithHoles(int aOutline)
Function IterateWithHoles.
Class SHAPE_POLY_SET.
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:1011
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc_stuff.h:210
int GetNetCode() const
Function GetNetCode.
Definition: seg.h:36
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.cpp:178
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:982
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:169
VECTOR2I A
Definition: seg.h:46
unsigned GetPriority() const
Function GetPriority.
Definition: class_zone.h:101
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:65
VECTOR2I B
Definition: seg.h:47
void DRC::updatePointers ( )
private

Function updatePointers is a private helper function used to update needed pointers from the one pointer which is known not to change, m_pcbEditorFrame.

Definition at line 490 of file drc.cpp.

References PCB_BASE_FRAME::GetBoard(), DIALOG_DRC_CONTROL_BASE::m_ClearanceListBox, m_drcDialog, m_pcb, m_pcbEditorFrame, m_unconnected, DIALOG_DRC_CONTROL_BASE::m_UnconnectedListBox, DRCLISTBOX::SetList(), and DIALOG_DRC_CONTROL::UpdateDisplayedCounts().

Referenced by Drc(), DrcBlind(), ListUnconnectedPads(), RunTests(), and ShowDRCDialog().

491 {
492  // update my pointers, m_pcbEditorFrame is the only unchangeable one
494 
495  if( m_drcDialog ) // Use diag list boxes only in DRC dialog
496  {
499 
501  }
502 }
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc_stuff.h:212
void UpdateDisplayedCounts()
Definition: dialog_drc.cpp:734
void SetList(DRC_ITEM_LIST *aList)
Function SetList sets the DRC_ITEM_LIST for this listbox.
BOARD * GetBoard() const
DRCLISTBOX * m_UnconnectedListBox
BOARD * m_pcb
Definition: drc_stuff.h:211
DRCLISTBOX * m_ClearanceListBox
Class DRC_LIST_MARKERS is an implementation of the interface named DRC_ITEM_LIST which uses a BOARD i...
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc_stuff.h:210
Class DRC_LIST_UNCONNECTED is an implementation of the interface named DRC_ITEM_LIST which uses a vec...
DRC_LIST m_unconnected
list of unconnected pads, as DRC_ITEMs
Definition: drc_stuff.h:214

Friends And Related Function Documentation

friend class DIALOG_DRC_CONTROL
friend

Definition at line 166 of file drc_stuff.h.

Referenced by ShowDRCDialog().

Member Data Documentation

bool DRC::m_abortDRC
private

Definition at line 184 of file drc_stuff.h.

Referenced by DRC().

bool DRC::m_doCreateRptFile
private

Definition at line 176 of file drc_stuff.h.

Referenced by DestroyDRCDialog(), DRC(), and ShowDRCDialog().

bool DRC::m_doFootprintOverlapping
private

Definition at line 177 of file drc_stuff.h.

Referenced by doFootprintOverlappingDrc(), DRC(), and RunTests().

bool DRC::m_doKeepoutTest
private

Definition at line 175 of file drc_stuff.h.

Referenced by DRC(), and RunTests().

bool DRC::m_doNoCourtyardDefined
private

Definition at line 178 of file drc_stuff.h.

Referenced by doFootprintOverlappingDrc(), DRC(), and RunTests().

bool DRC::m_doPad2PadTest
private

Definition at line 172 of file drc_stuff.h.

Referenced by DRC(), and RunTests().

bool DRC::m_doUnconnectedTest
private

Definition at line 173 of file drc_stuff.h.

Referenced by DRC(), and RunTests().

bool DRC::m_doZonesTest
private

Definition at line 174 of file drc_stuff.h.

Referenced by DRC().

DIALOG_DRC_CONTROL* DRC::m_drcDialog
private

Definition at line 212 of file drc_stuff.h.

Referenced by DestroyDRCDialog(), DRC(), ShowDRCDialog(), and updatePointers().

bool DRC::m_drcInProgress
private

Definition at line 185 of file drc_stuff.h.

Referenced by DRC().

wxPoint DRC::m_padToTestPos
private
PCB_EDIT_FRAME* DRC::m_pcbEditorFrame
private

The pcb frame editor which owns the board.

Definition at line 210 of file drc_stuff.h.

Referenced by addMarkerToPcb(), DRC(), Drc(), RunTests(), ShowDRCDialog(), TestZoneToZoneOutline(), and updatePointers().

wxString DRC::m_rptFilename
private

Definition at line 180 of file drc_stuff.h.

Referenced by DestroyDRCDialog(), and ShowDRCDialog().

double DRC::m_segmAngle
private
wxPoint DRC::m_segmEnd
private
int DRC::m_segmLength
private
DRC_LIST DRC::m_unconnected
private

list of unconnected pads, as DRC_ITEMs

Definition at line 214 of file drc_stuff.h.

Referenced by testUnconnected(), updatePointers(), and ~DRC().

int DRC::m_xcliphi
private

Definition at line 207 of file drc_stuff.h.

Referenced by checkClearanceSegmToPad(), checkLine(), doTrackDrc(), and DRC().

int DRC::m_xcliplo
private

Definition at line 205 of file drc_stuff.h.

Referenced by checkClearanceSegmToPad(), checkLine(), doTrackDrc(), and DRC().

int DRC::m_ycliphi
private

Definition at line 208 of file drc_stuff.h.

Referenced by checkClearanceSegmToPad(), checkLine(), doTrackDrc(), and DRC().

int DRC::m_ycliplo
private

Definition at line 206 of file drc_stuff.h.

Referenced by checkClearanceSegmToPad(), checkLine(), doTrackDrc(), and DRC().


The documentation for this class was generated from the following files: