KiCad PCB EDA Suite
DRC Class Reference

Design Rule Checker object that performs all the DRC tests. More...

#include <drc.h>

Inheritance diagram for DRC:
PCB_TOOL_BASE TOOL_INTERACTIVE TOOL_BASE

Public Types

enum  RESET_REASON { RUN, MODEL_RELOAD, GAL_SWITCH }
 

Determines the reason of reset for a tool

More...
 

Public Member Functions

 DRC ()
 
 ~DRC ()
 
void Reset (RESET_REASON aReason) override
 Function Reset() Brings the tool to a known, initial state. More...
 
int TestZoneToZoneOutline (ZONE_CONTAINER *aZone, bool aCreateMarkers)
 Tests whether distance between zones complies with the DRC rules. More...
 
void ShowDRCDialog (wxWindow *aParent)
 Open a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and creates the MARKERS. More...
 
int ShowDRCDialog (const TOOL_EVENT &aEvent)
 
void DestroyDRCDialog (int aReason)
 Deletes this ui dialog box and zeros out its pointer to remember the state of the dialog's existence. More...
 
void RunTests (wxTextCtrl *aMessages=NULL)
 Run all the tests specified with a previous call to SetSettings() More...
 
virtual bool Init () override
 Function Init() Init() is called once upon a registration of the tool. More...
 
void SetEditModules (bool aEnabled)
 Function SetEditModules() More...
 
bool EditingModules () const
 
void Activate ()
 Function Activate() Runs the tool. More...
 
TOOL_MENUGetToolMenu ()
 
void SetContextMenu (ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
 Function SetContextMenu() More...
 
void RunMainStack (std::function< void()> aFunc)
 Function RunMainStack() More...
 
template<class T >
void Go (int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
 Function Go() More...
 
TOOL_EVENTWait (const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
 Function Wait() More...
 
TOOL_TYPE GetType () const
 Function GetType() Returns the type of the tool. More...
 
TOOL_ID GetId () const
 Function GetId() Returns the unique identifier of the tool. More...
 
const std::string & GetName () const
 Function GetName() Returns the name of the tool. More...
 
TOOL_MANAGERGetManager () const
 Function GetManager() Returns the instance of TOOL_MANAGER that takes care of the tool. More...
 
TOOL_SETTINGSGetSettings ()
 
bool IsToolActive () const
 

Static Public Member Functions

static void TestFootprints (NETLIST &aNetlist, BOARD *aPCB, EDA_UNITS_T aUnits, DRC_LIST &aDRCList)
 Test the board footprints against a netlist. More...
 

Protected Types

enum  INTERACTIVE_PLACEMENT_OPTIONS { IPO_ROTATE = 1, IPO_FLIP = 2, IPO_SINGLE_CLICK = 4, IPO_REPEAT = 8 }
 

Protected Member Functions

void doInteractiveItemPlacement (const std::string &aTool, INTERACTIVE_PLACER_BASE *aPlacer, const wxString &aCommitMessage, int aOptions=IPO_ROTATE|IPO_FLIP|IPO_REPEAT)
 Helper function for performing a common interactive idiom: wait for a left click, place an item there (perhaps with a dialog or other user interaction), then have it move with the mouse and respond to rotate/flip, etc. More...
 
KIGFX::PCB_VIEWview () const
 
KIGFX::VIEW_CONTROLScontrols () const
 
PCB_BASE_EDIT_FRAMEframe () const
 
BOARDboard () const
 
MODULEmodule () const
 
PCB_DISPLAY_OPTIONSdisplayOptions () const
 
PCB_DRAW_PANEL_GALcanvas () const
 
const PCBNEW_SELECTIONselection () const
 
PCBNEW_SELECTIONselection ()
 
void attachManager (TOOL_MANAGER *aManager)
 Function attachManager() More...
 
KIGFX::VIEWgetView () const
 Function getView() More...
 
KIGFX::VIEW_CONTROLSgetViewControls () const
 Function getViewControls() More...
 
template<typename T >
T * getEditFrame () const
 Function getEditFrame() More...
 
template<typename T >
T * getModel () const
 Function getModel() More...
 

Protected Attributes

bool m_editModules
 
TOOL_MENU m_menu
 functions below are not yet implemented - their interface may change More...
 
TOOL_TYPE m_type
 

Stores the type of the tool.

More...
 
TOOL_ID m_toolId
 

Unique identifier for the tool, assigned by a TOOL_MANAGER instance.

More...
 
std::string m_toolName
 

Name of the tool.

More...
 
TOOL_MANAGERm_toolMgr
 
TOOL_SETTINGS m_toolSettings
 

Private Member Functions

void setTransitions () override
 

Sets up handlers for various events.

More...
 
void updatePointers ()
 Update needed pointers from the one pointer which is known not to change. More...
 
void addMarkerToPcb (MARKER_PCB *aMarker)
 Adds a DRC marker to the PCB through the COMMIT mechanism. More...
 
bool testNetClasses ()
 Go 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)
 Perform the DRC on all tracks. More...
 
void testPad2Pad ()
 
void testDrilledHoles ()
 
void testUnconnected ()
 
void testZones ()
 
void testKeepoutAreas ()
 
void testCopperTextItem (BOARD_ITEM *aTextItem)
 
void testCopperDrawItem (DRAWSEGMENT *aDrawing)
 
void testCopperTextAndGraphics ()
 
void testDisabledLayers ()
 

Tests for items placed on disabled layers (causing false connections).

More...
 
void testOutline ()
 Test that the board outline is contiguous and composed of valid elements. More...
 
bool doNetClass (const std::shared_ptr< NETCLASS > &aNetClass, wxString &msg)
 
bool doPadToPadsDrc (D_PAD *aRefPad, D_PAD **aStart, D_PAD **aEnd, int x_limit)
 Test the clearance between aRefPad and other pads. More...
 
bool doTrackDrc (TRACK *aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterator aEndIt, bool aTestZones)
 Test the current segment. More...
 
void doFootprintOverlappingDrc ()
 Test for footprint courtyard overlaps. More...
 
bool checkClearancePadToPad (D_PAD *aRefPad, D_PAD *aPad)
 
bool checkClearanceSegmToPad (const D_PAD *aPad, int aSegmentWidth, int aMinDist)
 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)
 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_refillZones
 
bool m_reportAllTrackErrors
 
bool m_testFootprints
 
wxString m_rptFilename
 
MARKER_PCBm_currentMarker
 
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
 
SHAPE_POLY_SET m_board_outlines
 The board outline including cutouts. More...
 
DIALOG_DRC_CONTROLm_drcDialog
 
DRC_MARKER_FACTORY m_markerFactory
 Class that generates markers. More...
 
DRC_LIST m_unconnected
 list of unconnected pads, as DRC_ITEMs More...
 
DRC_LIST m_footprints
 list of footprint warnings, as DRC_ITEMs More...
 
bool m_drcRun
 
bool m_footprintsTested
 

Friends

class DIALOG_DRC_CONTROL
 

Detailed Description

Design Rule Checker object that 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 186 of file drc.h.

Member Enumeration Documentation

◆ INTERACTIVE_PLACEMENT_OPTIONS

Enumerator
IPO_ROTATE 
IPO_FLIP 
IPO_SINGLE_CLICK 
IPO_REPEAT 

Definition at line 109 of file pcb_tool_base.h.

◆ RESET_REASON

enum TOOL_BASE::RESET_REASON
inherited

Determines the reason of reset for a tool

Enumerator
RUN 

Tool is invoked after being inactive.

MODEL_RELOAD 

Model changes (required full reload)

GAL_SWITCH 

Rendering engine changes.

Definition at line 79 of file tool_base.h.

80  {
81  RUN,
82  MODEL_RELOAD,
83  GAL_SWITCH
84  };
Model changes (required full reload)
Definition: tool_base.h:82
Tool is invoked after being inactive.
Definition: tool_base.h:81
Rendering engine changes.
Definition: tool_base.h:83

Constructor & Destructor Documentation

◆ DRC()

DRC::DRC ( )

Definition at line 62 of file drc.cpp.

62  :
63  PCB_TOOL_BASE( "pcbnew.DRCTool" )
64 {
65  m_drcDialog = NULL;
66 
67  // establish initial values for everything:
68  m_doPad2PadTest = true; // enable pad to pad clearance tests
69  m_doUnconnectedTest = true; // enable unconnected tests
70  m_doZonesTest = false; // disable zone to items clearance tests
71  m_doKeepoutTest = true; // enable keepout areas to items clearance tests
72  m_refillZones = false; // Only fill zones if requested by user.
73  m_reportAllTrackErrors = false;
74  m_testFootprints = false;
75 
76  m_drcRun = false;
77  m_footprintsTested = false;
78 
79  m_doCreateRptFile = false;
80  // m_rptFilename set to empty by its constructor
81 
82  m_currentMarker = NULL;
83 
84  m_segmAngle = 0;
85  m_segmLength = 0;
86 
87  m_xcliplo = 0;
88  m_ycliplo = 0;
89  m_xcliphi = 0;
90  m_ycliphi = 0;
91 }
bool m_refillZones
Definition: drc.h:205
bool m_doCreateRptFile
Definition: drc.h:204
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc.h:239
int m_ycliplo
Definition: drc.h:232
int m_ycliphi
Definition: drc.h:234
int m_segmLength
Definition: drc.h:226
bool m_testFootprints
Definition: drc.h:207
bool m_doKeepoutTest
Definition: drc.h:203
bool m_doZonesTest
Definition: drc.h:202
bool m_reportAllTrackErrors
Definition: drc.h:206
bool m_drcRun
Definition: drc.h:244
int m_xcliphi
Definition: drc.h:233
bool m_doPad2PadTest
Definition: drc.h:200
PCB_TOOL_BASE(TOOL_ID aId, const std::string &aName)
Constructor.
Definition: pcb_tool_base.h:71
bool m_footprintsTested
Definition: drc.h:245
MARKER_PCB * m_currentMarker
Definition: drc.h:211
int m_xcliplo
Definition: drc.h:231
bool m_doUnconnectedTest
Definition: drc.h:201
double m_segmAngle
Definition: drc.h:225

References m_currentMarker, m_doCreateRptFile, m_doKeepoutTest, m_doPad2PadTest, m_doUnconnectedTest, m_doZonesTest, m_drcDialog, m_drcRun, m_footprintsTested, m_refillZones, m_reportAllTrackErrors, m_segmAngle, m_segmLength, m_testFootprints, m_xcliphi, m_xcliplo, m_ycliphi, and m_ycliplo.

◆ ~DRC()

DRC::~DRC ( )

Definition at line 94 of file drc.cpp.

95 {
96  for( DRC_ITEM* unconnectedItem : m_unconnected )
97  delete unconnectedItem;
98 
99  for( DRC_ITEM* footprintItem : m_footprints )
100  delete footprintItem;
101 }
Class DRC_ITEM is a holder for a DRC (in Pcbnew) or ERC (in Eeschema) error item.
Definition: drc_item.h:48
DRC_LIST m_footprints
list of footprint warnings, as DRC_ITEMs
Definition: drc.h:243
DRC_LIST m_unconnected
list of unconnected pads, as DRC_ITEMs
Definition: drc.h:242

References m_footprints, and m_unconnected.

Member Function Documentation

◆ Activate()

void TOOL_INTERACTIVE::Activate ( )
inherited

Function Activate() Runs the tool.

After activation, the tool starts receiving events until it is finished.

Definition at line 51 of file tool_interactive.cpp.

52 {
54 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
TOOL_ID m_toolId
Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
Definition: tool_base.h:214
bool InvokeTool(TOOL_ID aToolId)
Function InvokeTool() Calls a tool by sending a tool activation event to tool of given ID.

References TOOL_MANAGER::InvokeTool(), TOOL_BASE::m_toolId, and TOOL_BASE::m_toolMgr.

Referenced by AUTOPLACE_TOOL::autoplace(), EDIT_TOOL::copyToClipboard(), LIB_EDIT_TOOL::DeleteItemCursor(), PL_EDIT_TOOL::DeleteItemCursor(), SCH_EDIT_TOOL::DeleteItemCursor(), PCBNEW_CONTROL::DeleteItemCursor(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), PCB_TOOL_BASE::doInteractiveItemPlacement(), DRAWING_TOOL::DrawArc(), DRAWING_TOOL::DrawCircle(), DRAWING_TOOL::DrawDimension(), DRAWING_TOOL::DrawLine(), MICROWAVE_TOOL::drawMicrowaveInductor(), LIB_DRAWING_TOOLS::DrawShape(), PL_DRAWING_TOOLS::DrawShape(), SCH_DRAWING_TOOLS::DrawSheet(), DRAWING_TOOL::DrawZone(), PCB_EDITOR_CONTROL::DrillOrigin(), PAD_TOOL::EnumeratePads(), PCBNEW_CONTROL::GridSetOrigin(), SCH_EDITOR_CONTROL::HighlightNetCursor(), PCB_INSPECTION_TOOL::HighlightNetTool(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), PCB_INSPECTION_TOOL::LocalRatsnestTool(), PL_EDIT_TOOL::Main(), SCH_MOVE_TOOL::Main(), EE_POINT_EDITOR::Main(), PL_POINT_EDITOR::Main(), LIB_MOVE_TOOL::Main(), PCBNEW_PICKER_TOOL::Main(), PICKER_TOOL::Main(), ROUTER_TOOL::MainLoop(), LENGTH_TUNER_TOOL::MainLoop(), CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::MeasureTool(), GERBVIEW_SELECTION_TOOL::MeasureTool(), EDIT_TOOL::MeasureTool(), EDIT_TOOL::Move(), LIB_TREE::onContextMenu(), POINT_EDITOR::OnSelectionChange(), LIB_DRAWING_TOOLS::PlaceAnchor(), SCH_DRAWING_TOOLS::PlaceComponent(), SCH_DRAWING_TOOLS::PlaceImage(), DRAWING_TOOL::PlaceImportedGraphics(), PL_DRAWING_TOOLS::PlaceItem(), PCB_EDITOR_CONTROL::PlaceModule(), PCB_EDITOR_CONTROL::PlaceTarget(), DRAWING_TOOL::PlaceText(), EDIT_TOOL::Remove(), POSITION_RELATIVE_TOOL::SelectPositionRelativeItem(), DRAWING_TOOL::SetAnchor(), ShowDRCDialog(), SCH_DRAWING_TOOLS::SingleClickPlace(), LIB_DRAWING_TOOLS::TwoClickPlace(), SCH_DRAWING_TOOLS::TwoClickPlace(), and SCH_LINE_WIRE_BUS_TOOL::UnfoldBus().

◆ addMarkerToPcb()

void DRC::addMarkerToPcb ( MARKER_PCB aMarker)
private

Adds a DRC marker to the PCB through the COMMIT mechanism.

Definition at line 164 of file drc.cpp.

165 {
166  BOARD_COMMIT commit( m_pcbEditorFrame );
167  commit.Add( aMarker );
168  commit.Push( wxEmptyString, false, false );
169 }
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:236

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

Referenced by doFootprintOverlappingDrc(), doNetClass(), doTrackDrc(), testCopperDrawItem(), testCopperTextItem(), testDisabledLayers(), testDrilledHoles(), testKeepoutAreas(), testOutline(), testPad2Pad(), testTracks(), and testZones().

◆ attachManager()

void TOOL_BASE::attachManager ( TOOL_MANAGER aManager)
protectedinherited

Function attachManager()

Sets the TOOL_MANAGER the tool will belong to. Called by TOOL_MANAGER::RegisterTool()

Definition at line 60 of file tool_base.cpp.

61 {
62  m_toolMgr = aManager;
63  m_toolSettings = TOOL_SETTINGS( this );
64 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
TOOL_SETTINGS m_toolSettings
Definition: tool_base.h:220
friend class TOOL_SETTINGS
Definition: tool_base.h:154

References TOOL_BASE::m_toolMgr, TOOL_BASE::m_toolSettings, and TOOL_BASE::TOOL_SETTINGS.

Referenced by TOOL_MANAGER::RegisterTool().

◆ board()

BOARD* PCB_TOOL_BASE::board ( ) const
inlineprotectedinherited

Definition at line 151 of file pcb_tool_base.h.

151 { return getModel<BOARD>(); }

Referenced by PCBNEW_CONTROL::AppendBoard(), AUTOPLACE_TOOL::autoplace(), PCB_INSPECTION_TOOL::calculateSelectionRatsnest(), EDIT_TOOL::changeTrackWidthOnClick(), ZONE_FILLER_TOOL::CheckAllZones(), checkClearancePadToPad(), checkClearanceSegmToPad(), PCB_INSPECTION_TOOL::ClearHighlight(), EDIT_TOOL::copyToClipboard(), MICROWAVE_TOOL::createInductorBetween(), MODULE_EDITOR_TOOLS::CreatePadFromShapes(), ROUTER_TOOL::CustomTrackWidthDialog(), PCBNEW_CONTROL::DeleteItemCursor(), PCB_TOOL_BASE::doInteractiveItemPlacement(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), DRAWING_TOOL::drawSegment(), PAD_TOOL::EnumeratePads(), MODULE_EDITOR_TOOLS::ExplodePadToShapes(), ZONE_FILLER_TOOL::FillAllZones(), SELECTION_TOOL::filterSelection(), SELECTION_TOOL::getCollectorsGuide(), PCBNEW_CONTROL::GraphicDisplayMode(), PCB_INSPECTION_TOOL::highlightNet(), PCBNEW_CONTROL::LayerNext(), PCBNEW_CONTROL::LayerPrev(), PCB_INSPECTION_TOOL::LocalRatsnestTool(), PCB_TOOL_BASE::module(), PCBNEW_CONTROL::ModuleEdgeOutlines(), ROUTER_TOOL::onTrackViaSizeChanged(), ROUTER_TOOL::onViaCommand(), PCBNEW_CONTROL::PadDisplayMode(), PCBNEW_CONTROL::Paste(), PCBNEW_CONTROL::placeBoardItems(), PCB_EDITOR_CONTROL::PlaceModule(), PCB_EDITOR_CONTROL::PlaceTarget(), DRAWING_TOOL::PlaceText(), ROUTER_TOOL::prepareInteractive(), SELECTION_TOOL::RebuildSelection(), PNS::TOOL_BASE::Reset(), PCBNEW_CONTROL::Reset(), SELECTION_TOOL::Selectable(), SELECTION_TOOL::selectAllItemsConnectedToItem(), SELECTION_TOOL::selectAllItemsConnectedToTrack(), SELECTION_TOOL::selectAllItemsOnNet(), SELECTION_TOOL::selectAllItemsOnSheet(), SELECTION_TOOL::selectPoint(), testDisabledLayers(), TestZoneToZoneOutline(), PCBNEW_CONTROL::TrackDisplayMode(), PCBNEW_CONTROL::ViaDisplayMode(), PCBNEW_CONTROL::ZoneDisplayMode(), ZONE_FILLER_TOOL::ZoneFill(), PCB_EDITOR_CONTROL::ZoneMerge(), and ZONE_FILLER_TOOL::ZoneUnfillAll().

◆ canvas()

◆ checkClearancePadToPad()

bool DRC::checkClearancePadToPad ( D_PAD aRefPad,
D_PAD aPad 
)
private
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 743 of file drc_clearance_test_functions.cpp.

744 {
745  int dist;
746  double pad_angle;
747 
748  // Get the clearance between the 2 pads. this is the min distance between aRefPad and aPad
749  int dist_min = aRefPad->GetClearance( aPad );
750 
751  // relativePadPos is the aPad shape position relative to the aRefPad shape position
752  wxPoint relativePadPos = aPad->ShapePos() - aRefPad->ShapePos();
753 
754  dist = KiROUND( EuclideanNorm( relativePadPos ) );
755 
756  // Quick test: Clearance is OK if the bounding circles are further away than "dist_min"
757  int delta = dist - aRefPad->GetBoundingRadius() - aPad->GetBoundingRadius();
758 
759  if( delta >= dist_min )
760  return true;
761 
762  /* Here, pads are near and DRC depend on the pad shapes
763  * We must compare distance using a fine shape analysis
764  * Because a circle or oval shape is the easier shape to test, try to have
765  * aRefPad shape type = PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL.
766  * if aRefPad = TRAP. and aPad = RECT, also swap pads
767  * Swap aRefPad and aPad if needed
768  */
769  bool swap_pads;
770  swap_pads = false;
771 
772  // swap pads to make comparisons easier
773  // Note also a ROUNDRECT pad with a corner radius = r can be considered as
774  // a smaller RECT (size - 2*r) with a clearance increased by r
775  // priority is aRefPad = ROUND then OVAL then RECT/ROUNDRECT then other
776  if( aRefPad->GetShape() != aPad->GetShape() && aRefPad->GetShape() != PAD_SHAPE_CIRCLE )
777  {
778  // pad ref shape is here oval, rect, roundrect, chamfered rect, trapezoid or custom
779  switch( aPad->GetShape() )
780  {
781  case PAD_SHAPE_CIRCLE:
782  swap_pads = true;
783  break;
784 
785  case PAD_SHAPE_OVAL:
786  swap_pads = true;
787  break;
788 
789  case PAD_SHAPE_RECT:
790  case PAD_SHAPE_ROUNDRECT:
791  if( aRefPad->GetShape() != PAD_SHAPE_OVAL )
792  swap_pads = true;
793  break;
794 
795  case PAD_SHAPE_TRAPEZOID:
797  case PAD_SHAPE_CUSTOM:
798  break;
799  }
800  }
801 
802  if( swap_pads )
803  {
804  std::swap( aRefPad, aPad );
805  relativePadPos = -relativePadPos;
806  }
807 
808  // corners of aRefPad (used only for rect/roundrect/trap pad)
809  wxPoint polyref[4];
810  // corners of aRefPad (used only for custom pad)
811  SHAPE_POLY_SET polysetref;
812 
813  // corners of aPad (used only for rect/roundrect/trap pad)
814  wxPoint polycompare[4];
815  // corners of aPad (used only custom pad)
816  SHAPE_POLY_SET polysetcompare;
817 
818  /* Because pad exchange, aRefPad shape is PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL,
819  * if one of the 2 pads was a PAD_SHAPE_CIRCLE or PAD_SHAPE_OVAL.
820  * Therefore, if aRefPad is a PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT or a PAD_SHAPE_TRAPEZOID,
821  * aPad is also a PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT or a PAD_SHAPE_TRAPEZOID
822  */
823  bool diag = true;
824 
825  switch( aRefPad->GetShape() )
826  {
827  case PAD_SHAPE_CIRCLE:
828 
829  /* One can use checkClearanceSegmToPad to test clearance
830  * aRefPad is like a track segment with a null length and a witdth = GetSize().x
831  */
832  m_segmLength = 0;
833  m_segmAngle = 0;
834 
835  m_segmEnd.x = m_segmEnd.y = 0;
836 
837  m_padToTestPos = relativePadPos;
838  diag = checkClearanceSegmToPad( aPad, aRefPad->GetSize().x, dist_min );
839  break;
840 
841  case PAD_SHAPE_TRAPEZOID:
842  case PAD_SHAPE_ROUNDRECT:
844  case PAD_SHAPE_RECT:
845  case PAD_SHAPE_CUSTOM:
846  // pad_angle = pad orient relative to the aRefPad orient
847  pad_angle = aRefPad->GetOrientation() + aPad->GetOrientation();
848  NORMALIZE_ANGLE_POS( pad_angle );
849 
850  if( aRefPad->GetShape() == PAD_SHAPE_ROUNDRECT )
851  {
852  int padRadius = aRefPad->GetRoundRectCornerRadius();
853  dist_min += padRadius;
854  GetRoundRectCornerCenters( polyref, padRadius, wxPoint( 0, 0 ), aRefPad->GetSize(),
855  aRefPad->GetOrientation() );
856  }
857  else if( aRefPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT )
858  {
859  auto board = aRefPad->GetBoard();
860  int maxError = ARC_HIGH_DEF;
861 
862  if( board )
863  maxError = board->GetDesignSettings().m_MaxError;
864 
865  // The reference pad can be rotated. calculate the rotated
866  // coordinates ( note, the ref pad position is the origin of
867  // coordinates for this drc test)
868  int padRadius = aRefPad->GetRoundRectCornerRadius();
869  TransformRoundChamferedRectToPolygon( polysetref, wxPoint( 0, 0 ), aRefPad->GetSize(),
870  aRefPad->GetOrientation(),
871  padRadius, aRefPad->GetChamferRectRatio(),
872  aRefPad->GetChamferPositions(), maxError );
873  }
874  else if( aRefPad->GetShape() == PAD_SHAPE_CUSTOM )
875  {
876  polysetref.Append( aRefPad->GetCustomShapeAsPolygon() );
877 
878  // The reference pad can be rotated. calculate the rotated
879  // coordiantes ( note, the ref pad position is the origin of
880  // coordinates for this drc test)
881  aRefPad->CustomShapeAsPolygonToBoardPosition( &polysetref, wxPoint( 0, 0 ),
882  aRefPad->GetOrientation() );
883  }
884  else
885  {
886  // BuildPadPolygon has meaning for rect a trapeziod shapes
887  // and returns the 4 corners
888  aRefPad->BuildPadPolygon( polyref, wxSize( 0, 0 ), aRefPad->GetOrientation() );
889  }
890 
891  switch( aPad->GetShape() )
892  {
893  case PAD_SHAPE_ROUNDRECT:
894  case PAD_SHAPE_RECT:
896  case PAD_SHAPE_TRAPEZOID:
897  case PAD_SHAPE_CUSTOM:
898  if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
899  {
900  int padRadius = aPad->GetRoundRectCornerRadius();
901  dist_min += padRadius;
902  GetRoundRectCornerCenters( polycompare, padRadius, relativePadPos, aPad->GetSize(),
903  aPad->GetOrientation() );
904  }
905  else if( aPad->GetShape() == PAD_SHAPE_CHAMFERED_RECT )
906  {
907  auto board = aRefPad->GetBoard();
908  int maxError = ARC_HIGH_DEF;
909 
910  if( board )
911  maxError = board->GetDesignSettings().m_MaxError;
912 
913  // The reference pad can be rotated. calculate the rotated
914  // coordinates ( note, the ref pad position is the origin of
915  // coordinates for this drc test)
916  int padRadius = aPad->GetRoundRectCornerRadius();
917  TransformRoundChamferedRectToPolygon( polysetcompare, relativePadPos,
918  aPad->GetSize(), aPad->GetOrientation(),
919  padRadius, aPad->GetChamferRectRatio(),
920  aPad->GetChamferPositions(), maxError );
921  }
922  else if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
923  {
924  polysetcompare.Append( aPad->GetCustomShapeAsPolygon() );
925 
926  // The pad to compare can be rotated. calculate the rotated
927  // coordinattes ( note, the pad to compare position
928  // is the relativePadPos for this drc test
929  aPad->CustomShapeAsPolygonToBoardPosition( &polysetcompare, relativePadPos,
930  aPad->GetOrientation() );
931  }
932  else
933  {
934  aPad->BuildPadPolygon( polycompare, wxSize( 0, 0 ), aPad->GetOrientation() );
935 
936  // Move aPad shape to relativePadPos
937  for( int ii = 0; ii < 4; ii++ )
938  polycompare[ii] += relativePadPos;
939  }
940  // And now test polygons: We have 3 cases:
941  // one poly is complex and the other is basic (has only 4 corners)
942  // both polys are complex
943  // both polys are basic (have only 4 corners) the most usual case
944  if( polysetref.OutlineCount() && polysetcompare.OutlineCount() == 0)
945  {
946  const SHAPE_LINE_CHAIN& refpoly = polysetref.COutline( 0 );
947  // And now test polygons:
948  if( !poly2polyDRC( (wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
949  polycompare, 4, dist_min ) ) // Therefore error
950  diag = false;
951  }
952  else if( polysetref.OutlineCount() == 0 && polysetcompare.OutlineCount())
953  {
954  const SHAPE_LINE_CHAIN& cmppoly = polysetcompare.COutline( 0 );
955  // And now test polygons:
956  if( !poly2polyDRC( (wxPoint*) &cmppoly.CPoint( 0 ), cmppoly.PointCount(),
957  polyref, 4, dist_min ) ) // Therefore error
958  diag = false;
959  }
960  else if( polysetref.OutlineCount() && polysetcompare.OutlineCount() )
961  {
962  const SHAPE_LINE_CHAIN& refpoly = polysetref.COutline( 0 );
963  const SHAPE_LINE_CHAIN& cmppoly = polysetcompare.COutline( 0 );
964 
965  // And now test polygons:
966  if( !poly2polyDRC( (wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
967  (wxPoint*) &cmppoly.CPoint( 0 ), cmppoly.PointCount(),
968  dist_min ) ) // Therefore error
969  diag = false;
970  }
971  else
972  {
973  if( !poly2polyDRC( polyref, 4, polycompare, 4, dist_min ) ) // Therefore error
974  diag = false;
975  }
976  break;
977 
978  default:
979  wxLogDebug( wxT( "DRC::checkClearancePadToPad: unexpected pad shape %d" ), aPad->GetShape() );
980  break;
981  }
982  break;
983 
984  case PAD_SHAPE_OVAL: /* an oval pad is like a track segment */
985  {
986  /* Create a track segment with same dimensions as the oval aRefPad
987  * and use checkClearanceSegmToPad function to test aPad to aRefPad clearance
988  */
989  int segm_width;
990  m_segmAngle = aRefPad->GetOrientation(); // Segment orient.
991 
992  if( aRefPad->GetSize().y < aRefPad->GetSize().x ) // Build an horizontal equiv segment
993  {
994  segm_width = aRefPad->GetSize().y;
995  m_segmLength = aRefPad->GetSize().x - aRefPad->GetSize().y;
996  }
997  else // Vertical oval: build an horizontal equiv segment and rotate 90.0 deg
998  {
999  segm_width = aRefPad->GetSize().x;
1000  m_segmLength = aRefPad->GetSize().y - aRefPad->GetSize().x;
1001  m_segmAngle += 900;
1002  }
1003 
1004  /* the start point must be 0,0 and currently relativePadPos
1005  * is relative the center of pad coordinate */
1006  wxPoint segstart;
1007  segstart.x = -m_segmLength / 2; // Start point coordinate of the horizontal equivalent segment
1008 
1009  RotatePoint( &segstart, m_segmAngle ); // actual start point coordinate of the equivalent segment
1010  // Calculate segment end position relative to the segment origin
1011  m_segmEnd.x = -2 * segstart.x;
1012  m_segmEnd.y = -2 * segstart.y;
1013 
1014  // Recalculate the equivalent segment angle in 0,1 degrees
1015  // to prepare a call to checkClearanceSegmToPad()
1017 
1018  // move pad position relative to the segment origin
1019  m_padToTestPos = relativePadPos - segstart;
1020 
1021  // Use segment to pad check to test the second pad:
1022  diag = checkClearanceSegmToPad( aPad, segm_width, dist_min );
1023  break;
1024  }
1025 
1026  default:
1027  wxLogDebug( wxT( "DRC::checkClearancePadToPad: unknown pad shape" ) );
1028  break;
1029  }
1030 
1031  return diag;
1032 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:123
bool poly2polyDRC(wxPoint *aTref, int aTrefCount, wxPoint *aTtest, int aTtestCount, int aDist)
compare 2 convex polygons and return true if distance > aDist (if no error DRC) i....
int OutlineCount() const
Returns the number of outlines in the set
static const int dist[10][10]
Definition: ar_matrix.cpp:320
BOARD * board() const
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aApproxErrorMax, int aMinSegPerCircleCount)
convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corner...
int m_segmLength
Definition: drc.h:226
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:540
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:206
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:252
int PointCount() const
Function PointCount()
wxPoint m_padToTestPos
Definition: drc.h:217
int GetChamferPositions() const
has meaning only for chamfered rect pads
Definition: class_pad.h:693
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:160
Class SHAPE_POLY_SET.
double GetChamferRectRatio() const
has meaning only for chamfered rect pads
Definition: class_pad.h:670
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:622
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
bool checkClearanceSegmToPad(const D_PAD *aPad, int aSegmentWidth, int aMinDist)
Check the distance from a pad to segment.
wxPoint m_segmEnd
Definition: drc.h:218
Class SHAPE_LINE_CHAIN.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:406
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0,...
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
wxPoint ShapePos() const
Definition: class_pad.cpp:570
const SHAPE_POLY_SET & GetCustomShapeAsPolygon() const
Accessor to the custom shape as one polygon.
Definition: class_pad.h:358
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:596
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:546
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:221
const wxSize & GetSize() const
Definition: class_pad.h:284
double m_segmAngle
Definition: drc.h:225
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:114
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)

References SHAPE_POLY_SET::Append(), ArcTangente(), PCB_TOOL_BASE::board(), D_PAD::BuildPadPolygon(), checkClearanceSegmToPad(), SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), D_PAD::CustomShapeAsPolygonToBoardPosition(), dist, EuclideanNorm(), BOARD_ITEM::GetBoard(), D_PAD::GetBoundingRadius(), D_PAD::GetChamferPositions(), D_PAD::GetChamferRectRatio(), D_PAD::GetClearance(), D_PAD::GetCustomShapeAsPolygon(), BOARD::GetDesignSettings(), D_PAD::GetOrientation(), GetRoundRectCornerCenters(), D_PAD::GetRoundRectCornerRadius(), D_PAD::GetShape(), D_PAD::GetSize(), KiROUND(), BOARD_DESIGN_SETTINGS::m_MaxError, m_padToTestPos, m_segmAngle, m_segmEnd, m_segmLength, NORMALIZE_ANGLE_POS(), SHAPE_POLY_SET::OutlineCount(), PAD_SHAPE_CHAMFERED_RECT, 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(), and TransformRoundChamferedRectToPolygon().

Referenced by doPadToPadsDrc().

◆ checkClearanceSegmToPad()

bool DRC::checkClearanceSegmToPad ( const D_PAD aPad,
int  aSegmentWidth,
int  aMinDist 
)
private

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 1040 of file drc_clearance_test_functions.cpp.

1041 {
1042  // Note:
1043  // we are using a horizontal segment for test, because we know here
1044  // only the length and orientation+ of the segment
1045  // Therefore the coordinates of the shape of pad to compare
1046  // must be calculated in a axis system rotated by m_segmAngle
1047  // and centered to the segment origin, before they can be tested
1048  // against the segment
1049  // We are using:
1050  // m_padToTestPos the position of the pad shape in this axis system
1051  // m_segmAngle the axis system rotation
1052 
1053  int segmHalfWidth = aSegmentWidth / 2;
1054  int distToLine = segmHalfWidth + aMinDist;
1055 
1056  wxSize padHalfsize; // half dimension of the pad
1057 
1058  if( aPad->GetShape() == PAD_SHAPE_CUSTOM )
1059  {
1060  // For a custom pad, the pad size has no meaning, we only can
1061  // use the bounding radius
1062  padHalfsize.x = padHalfsize.y = aPad->GetBoundingRadius();
1063  }
1064  else
1065  {
1066  padHalfsize = aPad->GetSize() / 2;
1067  }
1068 
1069  if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID ) // The size is bigger, due to GetDelta() extra size
1070  {
1071  padHalfsize.x += std::abs(aPad->GetDelta().y) / 2; // Remember: GetDelta().y is the GetSize().x change
1072  padHalfsize.y += std::abs(aPad->GetDelta().x) / 2; // Remember: GetDelta().x is the GetSize().y change
1073  }
1074 
1075  if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
1076  {
1077  /* Easy case: just test the distance between segment and pad centre
1078  * calculate pad coordinates in the X,Y axis with X axis = segment to test
1079  */
1081  return checkMarginToCircle( m_padToTestPos, distToLine + padHalfsize.x, m_segmLength );
1082  }
1083 
1084  /* calculate the bounding box of the pad, including the clearance and the segment width
1085  * if the line from 0 to m_segmEnd does not intersect this bounding box,
1086  * the clearance is always OK
1087  * But if intersect, a better analysis of the pad shape must be done.
1088  */
1089  m_xcliplo = m_padToTestPos.x - distToLine - padHalfsize.x;
1090  m_ycliplo = m_padToTestPos.y - distToLine - padHalfsize.y;
1091  m_xcliphi = m_padToTestPos.x + distToLine + padHalfsize.x;
1092  m_ycliphi = m_padToTestPos.y + distToLine + padHalfsize.y;
1093 
1094  wxPoint startPoint( 0, 0 );
1095  wxPoint endPoint = m_segmEnd;
1096 
1097  double orient = aPad->GetOrientation();
1098 
1099  RotatePoint( &startPoint, m_padToTestPos, -orient );
1100  RotatePoint( &endPoint, m_padToTestPos, -orient );
1101 
1102  if( checkLine( startPoint, endPoint ) )
1103  return true;
1104 
1105  /* segment intersects the bounding box. But there is not always a DRC error.
1106  * A fine analysis of the pad shape must be done.
1107  */
1108  switch( aPad->GetShape() )
1109  {
1110  case PAD_SHAPE_CIRCLE:
1111  // This case was already tested, so it cannot be found here.
1112  // it is here just to avoid compil warning, and to remember
1113  // it is already tested.
1114  return false;
1115 
1116  case PAD_SHAPE_OVAL:
1117  {
1118  /* an oval is a complex shape, but is a rectangle and 2 circles
1119  * these 3 basic shapes are more easy to test.
1120  *
1121  * In calculations we are using a vertical or horizontal oval shape
1122  * (i.e. a vertical or horizontal rounded segment)
1123  */
1124  wxPoint cstart = m_padToTestPos;
1125  wxPoint cend = m_padToTestPos; // center of each circle
1126  int delta = std::abs( padHalfsize.y - padHalfsize.x );
1127  int radius = std::min( padHalfsize.y, padHalfsize.x );
1128 
1129  if( padHalfsize.x > padHalfsize.y ) // horizontal equivalent segment
1130  {
1131  cstart.x -= delta;
1132  cend.x += delta;
1133  // Build the rectangular clearance area between the two circles
1134  // the rect starts at cstart.x and ends at cend.x and its height
1135  // is (radius + distToLine)*2
1136  m_xcliplo = cstart.x;
1137  m_ycliplo = cstart.y - radius - distToLine;
1138  m_xcliphi = cend.x;
1139  m_ycliphi = cend.y + radius + distToLine;
1140  }
1141  else // vertical equivalent segment
1142  {
1143  cstart.y -= delta;
1144  cend.y += delta;
1145  // Build the rectangular clearance area between the two circles
1146  // the rect starts at cstart.y and ends at cend.y and its width
1147  // is (radius + distToLine)*2
1148  m_xcliplo = cstart.x - distToLine - radius;
1149  m_ycliplo = cstart.y;
1150  m_xcliphi = cend.x + distToLine + radius;
1151  m_ycliphi = cend.y;
1152  }
1153 
1154  // Test the rectangular clearance area between the two circles (the rounded ends)
1155  // If the segment legth is zero, only check the endpoints, skip the rectangle
1156  if( m_segmLength && !checkLine( startPoint, endPoint ) )
1157  {
1158  return false;
1159  }
1160 
1161  // test the first end
1162  // Calculate the actual position of the circle, given the pad orientation:
1163  RotatePoint( &cstart, m_padToTestPos, orient );
1164 
1165  // Calculate the actual position of the circle in the new X,Y axis, relative
1166  // to the segment:
1167  RotatePoint( &cstart, m_segmAngle );
1168 
1169  if( !checkMarginToCircle( cstart, radius + distToLine, m_segmLength ) )
1170  {
1171  return false;
1172  }
1173 
1174  // test the second end
1175  RotatePoint( &cend, m_padToTestPos, orient );
1176  RotatePoint( &cend, m_segmAngle );
1177 
1178  if( !checkMarginToCircle( cend, radius + distToLine, m_segmLength ) )
1179  {
1180  return false;
1181  }
1182  }
1183  break;
1184 
1185  case PAD_SHAPE_ROUNDRECT:
1186  {
1187  // a round rect is a smaller rect, with a clearance augmented by the corners radius
1188  int r = aPad->GetRoundRectCornerRadius();
1189  padHalfsize.x -= r;
1190  padHalfsize.y -= r;
1191  distToLine += r;
1192  }
1193  // Fall through
1194  case PAD_SHAPE_RECT:
1195  // the area to test is a rounded rectangle.
1196  // this can be done by testing 2 rectangles and 4 circles (the corners)
1197 
1198  // Testing the first rectangle dimx + distToLine, dimy:
1199  m_xcliplo = m_padToTestPos.x - padHalfsize.x - distToLine;
1200  m_ycliplo = m_padToTestPos.y - padHalfsize.y;
1201  m_xcliphi = m_padToTestPos.x + padHalfsize.x + distToLine;
1202  m_ycliphi = m_padToTestPos.y + padHalfsize.y;
1203 
1204  if( !checkLine( startPoint, endPoint ) )
1205  return false;
1206 
1207  // Testing the second rectangle dimx , dimy + distToLine
1208  m_xcliplo = m_padToTestPos.x - padHalfsize.x;
1209  m_ycliplo = m_padToTestPos.y - padHalfsize.y - distToLine;
1210  m_xcliphi = m_padToTestPos.x + padHalfsize.x;
1211  m_ycliphi = m_padToTestPos.y + padHalfsize.y + distToLine;
1212 
1213  if( !checkLine( startPoint, endPoint ) )
1214  return false;
1215 
1216  // testing the 4 circles which are the clearance area of each corner:
1217 
1218  // testing the left top corner of the rectangle
1219  startPoint.x = m_padToTestPos.x - padHalfsize.x;
1220  startPoint.y = m_padToTestPos.y - padHalfsize.y;
1221  RotatePoint( &startPoint, m_padToTestPos, orient );
1222  RotatePoint( &startPoint, m_segmAngle );
1223 
1224  if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
1225  return false;
1226 
1227  // testing the right top corner of the rectangle
1228  startPoint.x = m_padToTestPos.x + padHalfsize.x;
1229  startPoint.y = m_padToTestPos.y - padHalfsize.y;
1230  RotatePoint( &startPoint, m_padToTestPos, orient );
1231  RotatePoint( &startPoint, m_segmAngle );
1232 
1233  if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
1234  return false;
1235 
1236  // testing the left bottom corner of the rectangle
1237  startPoint.x = m_padToTestPos.x - padHalfsize.x;
1238  startPoint.y = m_padToTestPos.y + padHalfsize.y;
1239  RotatePoint( &startPoint, m_padToTestPos, orient );
1240  RotatePoint( &startPoint, m_segmAngle );
1241 
1242  if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
1243  return false;
1244 
1245  // testing the right bottom corner of the rectangle
1246  startPoint.x = m_padToTestPos.x + padHalfsize.x;
1247  startPoint.y = m_padToTestPos.y + padHalfsize.y;
1248  RotatePoint( &startPoint, m_padToTestPos, orient );
1249  RotatePoint( &startPoint, m_segmAngle );
1250 
1251  if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
1252  return false;
1253 
1254  break;
1255 
1256  case PAD_SHAPE_TRAPEZOID:
1257  {
1258  wxPoint poly[4];
1259  aPad->BuildPadPolygon( poly, wxSize( 0, 0 ), orient );
1260 
1261  // Move shape to m_padToTestPos
1262  for( int ii = 0; ii < 4; ii++ )
1263  {
1264  poly[ii] += m_padToTestPos;
1265  RotatePoint( &poly[ii], m_segmAngle );
1266  }
1267 
1268  if( !poly2segmentDRC( poly, 4, wxPoint( 0, 0 ),
1269  wxPoint(m_segmLength,0), distToLine ) )
1270  return false;
1271  }
1272  break;
1273 
1274  case PAD_SHAPE_CUSTOM:
1275  {
1276  SHAPE_POLY_SET polyset;
1277  polyset.Append( aPad->GetCustomShapeAsPolygon() );
1278  // The pad can be rotated. calculate the coordinates
1279  // relatives to the segment being tested
1280  // Note, the pad position relative to the segment origin
1281  // is m_padToTestPos
1282  aPad->CustomShapeAsPolygonToBoardPosition( &polyset,
1283  m_padToTestPos, orient );
1284 
1285  // Rotate all coordinates by m_segmAngle, because the segment orient
1286  // is m_segmAngle
1287  // we are using a horizontal segment for test, because we know here
1288  // only the lenght and orientation+ of the segment
1289  // therefore all coordinates of the pad to test must be rotated by
1290  // m_segmAngle (they are already relative to the segment origin)
1291  aPad->CustomShapeAsPolygonToBoardPosition( &polyset,
1292  wxPoint( 0, 0 ), m_segmAngle );
1293 
1294  const SHAPE_LINE_CHAIN& refpoly = polyset.COutline( 0 );
1295 
1296  if( !poly2segmentDRC( (wxPoint*) &refpoly.CPoint( 0 ),
1297  refpoly.PointCount(),
1298  wxPoint( 0, 0 ), wxPoint(m_segmLength,0),
1299  distToLine ) )
1300  return false;
1301  }
1302  break;
1303 
1305  {
1306  auto board = aPad->GetBoard();
1307  int maxError = ARC_HIGH_DEF;
1308 
1309  if( board )
1310  maxError = board->GetDesignSettings().m_MaxError;
1311 
1312  SHAPE_POLY_SET polyset;
1313  // The pad can be rotated. calculate the coordinates
1314  // relatives to the segment being tested
1315  // Note, the pad position relative to the segment origin
1316  // is m_padToTestPos
1317  int padRadius = aPad->GetRoundRectCornerRadius();
1319  aPad->GetOrientation(),
1320  padRadius, aPad->GetChamferRectRatio(),
1321  aPad->GetChamferPositions(), maxError );
1322  // Rotate also coordinates by m_segmAngle, because the segment orient
1323  // is m_segmAngle.
1324  // we are using a horizontal segment for test, because we know here
1325  // only the lenght and orientation of the segment
1326  // therefore all coordinates of the pad to test must be rotated by
1327  // m_segmAngle (they are already relative to the segment origin)
1328  polyset.Rotate( DECIDEG2RAD( -m_segmAngle ), VECTOR2I( 0, 0 ) );
1329 
1330  const SHAPE_LINE_CHAIN& refpoly = polyset.COutline( 0 );
1331 
1332  if( !poly2segmentDRC( (wxPoint*) &refpoly.CPoint( 0 ),
1333  refpoly.PointCount(),
1334  wxPoint( 0, 0 ), wxPoint(m_segmLength,0),
1335  distToLine ) )
1336  return false;
1337  }
1338  break;
1339  }
1340 
1341  return true;
1342 }
BOARD * board() const
int m_ycliplo
Definition: drc.h:232
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aApproxErrorMax, int aMinSegPerCircleCount)
convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corner...
int m_ycliphi
Definition: drc.h:234
bool poly2segmentDRC(wxPoint *aTref, int aTrefCount, wxPoint aSegStart, wxPoint aSegEnd, int aDist)
int m_segmLength
Definition: drc.h:226
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:540
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:206
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
int PointCount() const
Function PointCount()
wxPoint m_padToTestPos
Definition: drc.h:217
#define abs(a)
Definition: auxiliary.h:84
int GetChamferPositions() const
has meaning only for chamfered rect pads
Definition: class_pad.h:693
bool checkLine(wxPoint aSegStart, wxPoint aSegEnd)
Function checkLine (helper function used in drc calculations to see if one track is in contact with a...
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
Class SHAPE_POLY_SET.
double GetChamferRectRatio() const
has meaning only for chamfered rect pads
Definition: class_pad.h:670
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
static bool checkMarginToCircle(wxPoint aCentre, int aRadius, int aLength)
Check the distance from a point to a segment.
int GetBoundingRadius() const
Function GetBoundingRadius returns the radius of a minimum sized circle which fully encloses this pad...
Definition: class_pad.h:622
const wxSize & GetDelta() const
Definition: class_pad.h:287
int m_xcliphi
Definition: drc.h:233
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
wxPoint m_segmEnd
Definition: drc.h:218
Class SHAPE_LINE_CHAIN.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:406
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0,...
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
const SHAPE_POLY_SET & GetCustomShapeAsPolygon() const
Accessor to the custom shape as one polygon.
Definition: class_pad.h:358
double DECIDEG2RAD(double deg)
Definition: trigo.h:214
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:546
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:221
const wxSize & GetSize() const
Definition: class_pad.h:284
void Rotate(double aAngle, const VECTOR2I &aCenter)
Function Rotate rotates all vertices by a given angle.
int m_xcliplo
Definition: drc.h:231
double m_segmAngle
Definition: drc.h:225
#define min(a, b)
Definition: auxiliary.h:85
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)

References abs, SHAPE_POLY_SET::Append(), PCB_TOOL_BASE::board(), D_PAD::BuildPadPolygon(), checkLine(), checkMarginToCircle(), SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), D_PAD::CustomShapeAsPolygonToBoardPosition(), DECIDEG2RAD(), BOARD_ITEM::GetBoard(), D_PAD::GetBoundingRadius(), D_PAD::GetChamferPositions(), D_PAD::GetChamferRectRatio(), D_PAD::GetCustomShapeAsPolygon(), D_PAD::GetDelta(), BOARD::GetDesignSettings(), D_PAD::GetOrientation(), D_PAD::GetRoundRectCornerRadius(), D_PAD::GetShape(), D_PAD::GetSize(), BOARD_DESIGN_SETTINGS::m_MaxError, m_padToTestPos, m_segmAngle, m_segmEnd, m_segmLength, m_xcliphi, m_xcliplo, m_ycliphi, m_ycliplo, min, PAD_SHAPE_CHAMFERED_RECT, PAD_SHAPE_CIRCLE, PAD_SHAPE_CUSTOM, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, SHAPE_LINE_CHAIN::PointCount(), poly2segmentDRC(), SHAPE_POLY_SET::Rotate(), RotatePoint(), and TransformRoundChamferedRectToPolygon().

Referenced by checkClearancePadToPad(), and doTrackDrc().

◆ checkLine()

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 1404 of file drc_clearance_test_functions.cpp.

1405 {
1406 #define WHEN_OUTSIDE return true
1407 #define WHEN_INSIDE
1408  int temp;
1409 
1410  if( aSegStart.x > aSegEnd.x )
1411  std::swap( aSegStart, aSegEnd );
1412 
1413  if( (aSegEnd.x <= m_xcliplo) || (aSegStart.x >= m_xcliphi) )
1414  {
1415  WHEN_OUTSIDE;
1416  }
1417 
1418  if( aSegStart.y < aSegEnd.y )
1419  {
1420  if( (aSegEnd.y <= m_ycliplo) || (aSegStart.y >= m_ycliphi) )
1421  {
1422  WHEN_OUTSIDE;
1423  }
1424 
1425  if( aSegStart.y < m_ycliplo )
1426  {
1427  temp = USCALE( (aSegEnd.x - aSegStart.x), (m_ycliplo - aSegStart.y),
1428  (aSegEnd.y - aSegStart.y) );
1429 
1430  if( (aSegStart.x += temp) >= m_xcliphi )
1431  {
1432  WHEN_OUTSIDE;
1433  }
1434 
1435  aSegStart.y = m_ycliplo;
1436  WHEN_INSIDE;
1437  }
1438 
1439  if( aSegEnd.y > m_ycliphi )
1440  {
1441  temp = USCALE( (aSegEnd.x - aSegStart.x), (aSegEnd.y - m_ycliphi),
1442  (aSegEnd.y - aSegStart.y) );
1443 
1444  if( (aSegEnd.x -= temp) <= m_xcliplo )
1445  {
1446  WHEN_OUTSIDE;
1447  }
1448 
1449  aSegEnd.y = m_ycliphi;
1450  WHEN_INSIDE;
1451  }
1452 
1453  if( aSegStart.x < m_xcliplo )
1454  {
1455  temp = USCALE( (aSegEnd.y - aSegStart.y), (m_xcliplo - aSegStart.x),
1456  (aSegEnd.x - aSegStart.x) );
1457  aSegStart.y += temp;
1458  aSegStart.x = m_xcliplo;
1459  WHEN_INSIDE;
1460  }
1461 
1462  if( aSegEnd.x > m_xcliphi )
1463  {
1464  temp = USCALE( (aSegEnd.y - aSegStart.y), (aSegEnd.x - m_xcliphi),
1465  (aSegEnd.x - aSegStart.x) );
1466  aSegEnd.y -= temp;
1467  aSegEnd.x = m_xcliphi;
1468  WHEN_INSIDE;
1469  }
1470  }
1471  else
1472  {
1473  if( (aSegStart.y <= m_ycliplo) || (aSegEnd.y >= m_ycliphi) )
1474  {
1475  WHEN_OUTSIDE;
1476  }
1477 
1478  if( aSegStart.y > m_ycliphi )
1479  {
1480  temp = USCALE( (aSegEnd.x - aSegStart.x), (aSegStart.y - m_ycliphi),
1481  (aSegStart.y - aSegEnd.y) );
1482 
1483  if( (aSegStart.x += temp) >= m_xcliphi )
1484  {
1485  WHEN_OUTSIDE;
1486  }
1487 
1488  aSegStart.y = m_ycliphi;
1489  WHEN_INSIDE;
1490  }
1491 
1492  if( aSegEnd.y < m_ycliplo )
1493  {
1494  temp = USCALE( (aSegEnd.x - aSegStart.x), (m_ycliplo - aSegEnd.y),
1495  (aSegStart.y - aSegEnd.y) );
1496 
1497  if( (aSegEnd.x -= temp) <= m_xcliplo )
1498  {
1499  WHEN_OUTSIDE;
1500  }
1501 
1502  aSegEnd.y = m_ycliplo;
1503  WHEN_INSIDE;
1504  }
1505 
1506  if( aSegStart.x < m_xcliplo )
1507  {
1508  temp = USCALE( (aSegStart.y - aSegEnd.y), (m_xcliplo - aSegStart.x),
1509  (aSegEnd.x - aSegStart.x) );
1510  aSegStart.y -= temp;
1511  aSegStart.x = m_xcliplo;
1512  WHEN_INSIDE;
1513  }
1514 
1515  if( aSegEnd.x > m_xcliphi )
1516  {
1517  temp = USCALE( (aSegStart.y - aSegEnd.y), (aSegEnd.x - m_xcliphi),
1518  (aSegEnd.x - aSegStart.x) );
1519  aSegEnd.y += temp;
1520  aSegEnd.x = m_xcliphi;
1521  WHEN_INSIDE;
1522  }
1523  }
1524 
1525  // Do not divide here to avoid rounding errors
1526  if( ( (aSegEnd.x + aSegStart.x) < m_xcliphi * 2 )
1527  && ( (aSegEnd.x + aSegStart.x) > m_xcliplo * 2) \
1528  && ( (aSegEnd.y + aSegStart.y) < m_ycliphi * 2 )
1529  && ( (aSegEnd.y + aSegStart.y) > m_ycliplo * 2 ) )
1530  {
1531  return false;
1532  }
1533  else
1534  {
1535  return true;
1536  }
1537 }
static int USCALE(unsigned arg, unsigned num, unsigned den)
#define WHEN_OUTSIDE
int m_ycliplo
Definition: drc.h:232
int m_ycliphi
Definition: drc.h:234
int m_xcliphi
Definition: drc.h:233
#define WHEN_INSIDE
int m_xcliplo
Definition: drc.h:231

References m_xcliphi, m_xcliplo, m_ycliphi, m_ycliplo, USCALE(), WHEN_INSIDE, and WHEN_OUTSIDE.

Referenced by checkClearanceSegmToPad(), and doTrackDrc().

◆ checkMarginToCircle()

bool DRC::checkMarginToCircle ( wxPoint  aCentre,
int  aRadius,
int  aLength 
)
staticprivate

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 1351 of file drc_clearance_test_functions.cpp.

1352 {
1353  if( abs( aCentre.y ) >= aRadius ) // trivial case
1354  return true;
1355 
1356  // Here, distance between aCentre and X axis is < aRadius
1357  if( (aCentre.x > -aRadius ) && ( aCentre.x < (aLength + aRadius) ) )
1358  {
1359  if( (aCentre.x >= 0) && (aCentre.x <= aLength) )
1360  return false; // aCentre is between the starting point and the ending point of the segm
1361 
1362  if( aCentre.x > aLength ) // aCentre is after the ending point
1363  aCentre.x -= aLength; // move aCentre to the starting point of the segment
1364 
1365  if( EuclideanNorm( aCentre ) < aRadius )
1366  // distance between aCentre and the starting point or the ending point is < aRadius
1367  return false;
1368  }
1369 
1370  return true;
1371 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:123
#define abs(a)
Definition: auxiliary.h:84

References abs, and EuclideanNorm().

Referenced by checkClearanceSegmToPad(), and doTrackDrc().

◆ controls()

◆ DestroyDRCDialog()

void DRC::DestroyDRCDialog ( int  aReason)

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 172 of file drc.cpp.

173 {
174  if( m_drcDialog )
175  {
177 
178  m_drcDialog->Destroy();
179  m_drcDialog = nullptr;
180  }
181 }
bool m_doCreateRptFile
Definition: drc.h:204
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc.h:239
void GetRptSettings(bool *aEnable, wxString &aFileName)
Definition: dialog_drc.cpp:202
wxString m_rptFilename
Definition: drc.h:209

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

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

◆ displayOptions()

◆ doFootprintOverlappingDrc()

void DRC::doFootprintOverlappingDrc ( )
private

Test for footprint courtyard overlaps.

Definition at line 1342 of file drc.cpp.

1343 {
1344  DRC_COURTYARD_OVERLAP drc_overlap(
1345  m_markerFactory, [&]( MARKER_PCB* aMarker ) { addMarkerToPcb( aMarker ); } );
1346 
1347  drc_overlap.RunDRC( *m_pcb );
1348 }
BOARD * m_pcb
Definition: drc.h:237
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
bool RunDRC(BOARD &aBoard) const override
Runs this provider against the given PCB with configured options (if any).
A class that provides the courtyard-based DRC checks.
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240

References addMarkerToPcb(), m_markerFactory, m_pcb, and DRC_COURTYARD_OVERLAP::RunDRC().

Referenced by RunTests().

◆ doInteractiveItemPlacement()

void PCB_TOOL_BASE::doInteractiveItemPlacement ( const std::string &  aTool,
INTERACTIVE_PLACER_BASE aPlacer,
const wxString &  aCommitMessage,
int  aOptions = IPO_ROTATE | IPO_FLIP | IPO_REPEAT 
)
protectedinherited

Helper function for performing a common interactive idiom: wait for a left click, place an item there (perhaps with a dialog or other user interaction), then have it move with the mouse and respond to rotate/flip, etc.

More complex interactive processes are not supported here, you should implement a customised event loop for those.

Parameters
aItemCreatorthe callable that will attempt to create the item
aCommitMessagethe message used on a successful commit

Definition at line 36 of file pcb_tool_base.cpp.

39 {
40  using namespace std::placeholders;
41  std::unique_ptr<BOARD_ITEM> newItem;
42 
43  frame()->PushTool( aTool );
44  Activate();
45 
46  BOARD_COMMIT commit( frame() );
47 
49 
50  // do not capture or auto-pan until we start placing an item
51  controls()->ShowCursor( true );
52  controls()->SetSnapping( true );
53 
54  // Add a VIEW_GROUP that serves as a preview for the new item
55  PCBNEW_SELECTION preview;
56  view()->Add( &preview );
57 
58  aPlacer->m_board = board();
59  aPlacer->m_frame = frame();
60  aPlacer->m_modifiers = 0;
61 
62  auto makeNewItem = [&] ( VECTOR2I aPosition )
63  {
64  if( frame()->GetModel() )
65  newItem = aPlacer->CreateItem();
66 
67  if( newItem )
68  {
69  newItem->SetPosition( (wxPoint) aPosition );
70  preview.Add( newItem.get() );
71 
72  if( newItem->Type() == PCB_MODULE_T )
73  {
74  auto module = dyn_cast<MODULE*>( newItem.get() );
75 
76  // modules have more drawable parts
77  module->RunOnChildren( std::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) );
78  }
79  }
80  };
81 
82  if( aOptions & IPO_SINGLE_CLICK )
83  makeNewItem( controls()->GetCursorPosition() );
84 
85  // Main loop: keep receiving events
86  while( TOOL_EVENT* evt = Wait() )
87  {
88  VECTOR2I cursorPos = controls()->GetCursorPosition();
89  aPlacer->m_modifiers = evt->Modifier();
90 
91  auto cleanup = [&] ()
92  {
93  newItem = nullptr;
94  preview.Clear();
95  view()->Update( &preview );
96  controls()->SetAutoPan( false );
97  controls()->CaptureCursor( false );
98  controls()->ShowCursor( true );
99  };
100 
101  if( evt->IsCancelInteractive() )
102  {
103  if( aOptions & IPO_SINGLE_CLICK )
104  {
105  cleanup();
106  frame()->PopTool( aTool );
107  break;
108  }
109  else if( newItem )
110  cleanup();
111  else
112  {
113  frame()->PopTool( aTool );
114  break;
115  }
116  }
117  else if( evt->IsActivate() )
118  {
119  if( newItem )
120  cleanup();
121 
122  if( evt->IsPointEditor() )
123  {
124  // don't exit (the point editor runs in the background)
125  }
126  else if( evt->IsMoveTool() )
127  {
128  // leave ourselves on the stack so we come back after the move
129  break;
130  }
131  else
132  {
133  frame()->PopTool( aTool );
134  break;
135  }
136  }
137  else if( evt->IsClick( BUT_LEFT ) )
138  {
139  if( !newItem )
140  {
141  // create the item if possible
142  makeNewItem( cursorPos );
143 
144  // no item created, so wait for another click
145  if( !newItem )
146  continue;
147 
148  controls()->CaptureCursor( true );
149  controls()->SetAutoPan( true );
150  }
151  else
152  {
153  auto oldFlags = newItem->GetFlags();
154  newItem->ClearFlags();
155 
156  if( !aPlacer->PlaceItem( newItem.get(), commit ) )
157  {
158  newItem->SetFlags( oldFlags );
159  continue;
160  }
161 
162  preview.Clear();
163  newItem.release();
164  commit.Push( aCommitMessage );
165 
166  controls()->CaptureCursor( false );
167  controls()->SetAutoPan( false );
168  controls()->ShowCursor( true );
169 
170  if( !( aOptions & IPO_REPEAT ) )
171  break;
172 
173  if( aOptions & IPO_SINGLE_CLICK )
174  makeNewItem( controls()->GetCursorPosition() );
175  }
176  }
177  else if( evt->IsClick( BUT_RIGHT ) )
178  {
180  }
181  else if( newItem && evt->Category() == TC_COMMAND )
182  {
183  /*
184  * Handle any events that can affect the item as we move
185  * it around, eg rotate and flip
186  */
187 
188  if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) && ( aOptions & IPO_ROTATE ) )
189  {
190  const int rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *frame(), *evt );
191  newItem->Rotate( newItem->GetPosition(), rotationAngle );
192  view()->Update( &preview );
193  }
194  else if( evt->IsAction( &PCB_ACTIONS::flip ) && ( aOptions & IPO_FLIP ) )
195  {
196  newItem->Flip( newItem->GetPosition(), frame()->Settings().m_FlipLeftRight );
197  view()->Update( &preview );
198  }
199  }
200 
201  else if( newItem && evt->IsMotion() )
202  {
203  // track the cursor
204  newItem->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
205  aPlacer->SnapItem( newItem.get() );
206 
207  // Show a preview of the item
208  view()->Update( &preview );
209  }
210 
211  else
212  evt->SetPassEvent();
213  }
214 
215  view()->Remove( &preview );
216 }
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:73
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
TOOL_MENU m_menu
functions below are not yet implemented - their interface may change
virtual void Clear() override
Function Clear() Removes all the stored items from the group.
Definition: selection.h:93
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction)
Function RunOnChildren.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
virtual bool PlaceItem(BOARD_ITEM *aItem, BOARD_COMMIT &aCommit)
BOARD * board() const
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags) override
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: pcb_view.cpp:91
virtual std::unique_ptr< BOARD_ITEM > CreateItem()=0
virtual void SetSnapping(bool aEnabled)
Function SetSnapping() Enables/disables snapping cursor to grid.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:109
bool IsRotateToolEvt(const TOOL_EVENT &aEvt)
Function isRotateToolEvt()
virtual void Remove(VIEW_ITEM *aItem) override
Function Remove() Removes a VIEW_ITEM from the view.
Definition: pcb_view.cpp:74
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:74
TOOL_MANAGER * GetManager() const
Function GetManager() Returns the instance of TOOL_MANAGER that takes care of the tool.
Definition: tool_base.h:143
PCB_BASE_EDIT_FRAME * frame() const
virtual void SnapItem(BOARD_ITEM *aItem)
class MODULE, a footprint
Definition: typeinfo.h:89
const PCBNEW_SELECTION & selection() const
virtual void CaptureCursor(bool aEnabled)
Function CaptureCursor() Forces the cursor to stay within the drawing panel area.
PCB_GENERAL_SETTINGS & Settings()
Class TOOL_EVENT.
Definition: tool_event.h:168
KIGFX::PCB_VIEW * view() const
virtual void Add(VIEW_ITEM *aItem)
Function Add() Adds an item to the group.
Definition: view_group.cpp:55
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:116
KIGFX::VIEW_CONTROLS * controls() const
MODULE * module() const
virtual void PopTool(const std::string &actionName)
void Activate()
Function Activate() Runs the tool.
virtual BOARD_ITEM_CONTAINER * GetModel() const =0
Function GetModel()
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Function Add() Adds a VIEW_ITEM to the view.
Definition: pcb_view.cpp:58
PCB_BASE_EDIT_FRAME * m_frame
Definition: pcb_tool_base.h:58
int GetEventRotationAngle(const PCB_BASE_EDIT_FRAME &aFrame, const TOOL_EVENT &aEvt)
Function getEventRotationAngle()
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:59
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.

References TOOL_INTERACTIVE::Activate(), KIGFX::PCB_VIEW::Add(), KIGFX::VIEW_GROUP::Add(), SELECTION::Add(), PCB_TOOL_BASE::board(), BUT_LEFT, BUT_RIGHT, KIGFX::VIEW_CONTROLS::CaptureCursor(), SELECTION::Clear(), PCB_TOOL_BASE::controls(), INTERACTIVE_PLACER_BASE::CreateItem(), PCB_ACTIONS::flip, PCB_TOOL_BASE::frame(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), TOOL_EVT_UTILS::GetEventRotationAngle(), TOOL_BASE::GetManager(), PCB_BASE_EDIT_FRAME::GetModel(), PCB_TOOL_BASE::IPO_FLIP, PCB_TOOL_BASE::IPO_REPEAT, PCB_TOOL_BASE::IPO_ROTATE, PCB_TOOL_BASE::IPO_SINGLE_CLICK, TOOL_EVT_UTILS::IsRotateToolEvt(), INTERACTIVE_PLACER_BASE::m_board, PCB_GENERAL_SETTINGS::m_FlipLeftRight, INTERACTIVE_PLACER_BASE::m_frame, TOOL_INTERACTIVE::m_menu, INTERACTIVE_PLACER_BASE::m_modifiers, PCB_TOOL_BASE::module(), PCB_MODULE_T, INTERACTIVE_PLACER_BASE::PlaceItem(), EDA_BASE_FRAME::PopTool(), BOARD_COMMIT::Push(), EDA_BASE_FRAME::PushTool(), KIGFX::PCB_VIEW::Remove(), TOOL_MANAGER::RunAction(), MODULE::RunOnChildren(), PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, KIGFX::VIEW_CONTROLS::SetAutoPan(), KIGFX::VIEW_CONTROLS::SetSnapping(), PCB_BASE_FRAME::Settings(), TOOL_MENU::ShowContextMenu(), KIGFX::VIEW_CONTROLS::ShowCursor(), INTERACTIVE_PLACER_BASE::SnapItem(), TC_COMMAND, KIGFX::PCB_VIEW::Update(), PCB_TOOL_BASE::view(), TOOL_INTERACTIVE::Wait(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by MICROWAVE_TOOL::addMicrowaveFootprint(), DRAWING_TOOL::DrawVia(), and MODULE_EDITOR_TOOLS::PlacePad().

◆ doNetClass()

bool DRC::doNetClass ( const std::shared_ptr< NETCLASS > &  aNetClass,
wxString &  msg 
)
private

Definition at line 539 of file drc.cpp.

540 {
541  bool ret = true;
542 
544 
545 #define FmtVal( x ) GetChars( StringFromValue( m_pcbEditorFrame->GetUserUnits(), x ) )
546 
547 #if 0 // set to 1 when (if...) BOARD_DESIGN_SETTINGS has a m_MinClearance value
548  if( nc->GetClearance() < g.m_MinClearance )
549  {
550  msg.Printf( _( "NETCLASS: \"%s\" has Clearance:%s which is less than global:%s" ),
551  GetChars( nc->GetName() ),
552  FmtVal( nc->GetClearance() ),
553  FmtVal( g.m_TrackClearance )
554  );
555 
557  m_currentMarker = nullptr;
558  ret = false;
559  }
560 #endif
561 
562  if( nc->GetTrackWidth() < g.m_TrackMinWidth )
563  {
564  msg.Printf( _( "NETCLASS: \"%s\" has TrackWidth:%s which is less than global:%s" ),
565  GetChars( nc->GetName() ),
566  FmtVal( nc->GetTrackWidth() ),
568  );
569 
571  ret = false;
572  }
573 
574  if( nc->GetViaDiameter() < g.m_ViasMinSize )
575  {
576  msg.Printf( _( "NETCLASS: \"%s\" has Via Dia:%s which is less than global:%s" ),
577  GetChars( nc->GetName() ),
578  FmtVal( nc->GetViaDiameter() ),
579  FmtVal( g.m_ViasMinSize )
580  );
581 
583  ret = false;
584  }
585 
586  if( nc->GetViaDrill() < g.m_ViasMinDrill )
587  {
588  msg.Printf( _( "NETCLASS: \"%s\" has Via Drill:%s which is less than global:%s" ),
589  GetChars( nc->GetName() ),
590  FmtVal( nc->GetViaDrill() ),
592  );
593 
595  ret = false;
596  }
597 
598  if( nc->GetuViaDiameter() < g.m_MicroViasMinSize )
599  {
600  msg.Printf( _( "NETCLASS: \"%s\" has uVia Dia:%s which is less than global:%s" ),
601  GetChars( nc->GetName() ),
602  FmtVal( nc->GetuViaDiameter() ),
603  FmtVal( g.m_MicroViasMinSize ) );
604 
606  ret = false;
607  }
608 
609  if( nc->GetuViaDrill() < g.m_MicroViasMinDrill )
610  {
611  msg.Printf( _( "NETCLASS: \"%s\" has uVia Drill:%s which is less than global:%s" ),
612  GetChars( nc->GetName() ),
613  FmtVal( nc->GetuViaDrill() ),
615 
617  ret = false;
618  }
619 
620  return ret;
621 }
#define DRCE_NETCLASS_TRACKWIDTH
netclass has TrackWidth < board.m_designSettings->m_TrackMinWidth
Definition: drc.h:77
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:540
#define DRCE_NETCLASS_CLEARANCE
netclass has Clearance < board.m_designSettings->m_TrackClearance
Definition: drc.h:78
BOARD * m_pcb
Definition: drc.h:237
#define DRCE_NETCLASS_uVIADRILLSIZE
netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill
Definition: drc.h:82
#define DRCE_NETCLASS_VIASIZE
netclass has ViaSize < board.m_designSettings->m_ViasMinSize
Definition: drc.h:79
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
int m_TrackMinWidth
track min value for width ((min copper size value
int m_ViasMinSize
vias (not micro vias) min diameter
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
int m_ViasMinDrill
vias (not micro vias) min drill diameter
#define DRCE_NETCLASS_VIADRILLSIZE
netclass has ViaDrillSize < board.m_designSettings->m_ViasMinDrill
Definition: drc.h:80
int m_MicroViasMinSize
micro vias (not vias) min diameter
#define _(s)
#define FmtVal(x)
MARKER_PCB * m_currentMarker
Definition: drc.h:211
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:101
int m_MicroViasMinDrill
micro vias (not vias) min drill diameter
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
#define DRCE_NETCLASS_uVIASIZE
netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize
Definition: drc.h:81
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.

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

Referenced by testNetClasses().

◆ doPadToPadsDrc()

bool DRC::doPadToPadsDrc ( D_PAD aRefPad,
D_PAD **  aStart,
D_PAD **  aEnd,
int  x_limit 
)
private

Test the clearance between aRefPad and other pads.

The pad list must be sorted by x coordinate.

Parameters
aRefPadis the pad to test
aStartis the first pad of the list to test against aRefPad
aEndis the end of the list and is not included
x_limitis used to stop the test (i.e. when the current pad pos X in list exceeds this limit, because the list is sorted by X coordinate)

Definition at line 1210 of file drc.cpp.

1211 {
1212  const static LSET all_cu = LSET::AllCuMask();
1213 
1214  LSET layerMask = aRefPad->GetLayerSet() & all_cu;
1215 
1216  /* used to test DRC pad to holes: this dummy pad has the size and shape of the hole
1217  * to test pad to pad hole DRC, using the pad to pad DRC test function.
1218  * Therefore, this dummy pad is a circle or an oval.
1219  * A pad must have a parent because some functions expect a non null parent
1220  * to find the parent board, and some other data
1221  */
1222  MODULE dummymodule( m_pcb ); // Creates a dummy parent
1223  D_PAD dummypad( &dummymodule );
1224 
1225  // Ensure the hole is on all copper layers
1226  dummypad.SetLayerSet( all_cu | dummypad.GetLayerSet() );
1227 
1228  // Use the minimal local clearance value for the dummy pad.
1229  // The clearance of the active pad will be used as minimum distance to a hole
1230  // (a value = 0 means use netclass value)
1231  dummypad.SetLocalClearance( 1 );
1232 
1233  for( D_PAD** pad_list = aStart; pad_list<aEnd; ++pad_list )
1234  {
1235  D_PAD* pad = *pad_list;
1236 
1237  if( pad == aRefPad )
1238  continue;
1239 
1240  // We can stop the test when pad->GetPosition().x > x_limit
1241  // because the list is sorted by X values
1242  if( pad->GetPosition().x > x_limit )
1243  break;
1244 
1245  // No problem if pads which are on copper layers are on different copper layers,
1246  // (pads can be only on a technical layer, to build complex pads)
1247  // but their hole (if any ) can create DRC error because they are on all
1248  // copper layers, so we test them
1249  if( ( pad->GetLayerSet() & layerMask ) == 0 &&
1250  ( pad->GetLayerSet() & all_cu ) != 0 &&
1251  ( aRefPad->GetLayerSet() & all_cu ) != 0 )
1252  {
1253  // if holes are in the same location and have the same size and shape,
1254  // this can be accepted
1255  if( pad->GetPosition() == aRefPad->GetPosition()
1256  && pad->GetDrillSize() == aRefPad->GetDrillSize()
1257  && pad->GetDrillShape() == aRefPad->GetDrillShape() )
1258  {
1259  if( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
1260  continue;
1261 
1262  // for oval holes: must also have the same orientation
1263  if( pad->GetOrientation() == aRefPad->GetOrientation() )
1264  continue;
1265  }
1266 
1267  /* Here, we must test clearance between holes and pads
1268  * dummy pad size and shape is adjusted to pad drill size and shape
1269  */
1270  if( pad->GetDrillSize().x )
1271  {
1272  // pad under testing has a hole, test this hole against pad reference
1273  dummypad.SetPosition( pad->GetPosition() );
1274  dummypad.SetSize( pad->GetDrillSize() );
1275  dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
1277  dummypad.SetOrientation( pad->GetOrientation() );
1278 
1279  if( !checkClearancePadToPad( aRefPad, &dummypad ) )
1280  {
1281  // here we have a drc error on pad!
1283  return false;
1284  }
1285  }
1286 
1287  if( aRefPad->GetDrillSize().x ) // pad reference has a hole
1288  {
1289  dummypad.SetPosition( aRefPad->GetPosition() );
1290  dummypad.SetSize( aRefPad->GetDrillSize() );
1291  dummypad.SetShape( aRefPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
1293  dummypad.SetOrientation( aRefPad->GetOrientation() );
1294 
1295  if( !checkClearancePadToPad( pad, &dummypad ) )
1296  {
1297  // here we have a drc error on aRefPad!
1299  return false;
1300  }
1301  }
1302 
1303  continue;
1304  }
1305 
1306  // The pad must be in a net (i.e pt_pad->GetNet() != 0 ),
1307  // But no problem if pads have the same netcode (same net)
1308  if( pad->GetNetCode() && ( aRefPad->GetNetCode() == pad->GetNetCode() ) )
1309  continue;
1310 
1311  // if pads are from the same footprint
1312  if( pad->GetParent() == aRefPad->GetParent() )
1313  {
1314  // and have the same pad number ( equivalent pads )
1315 
1316  // one can argue that this 2nd test is not necessary, that any
1317  // two pads from a single module are acceptable. This 2nd test
1318  // should eventually be a configuration option.
1319  if( pad->PadNameEqual( aRefPad ) )
1320  continue;
1321  }
1322 
1323  // if either pad has no drill and is only on technical layers, not a clearance violation
1324  if( ( ( pad->GetLayerSet() & layerMask ) == 0 && !pad->GetDrillSize().x ) ||
1325  ( ( aRefPad->GetLayerSet() & layerMask ) == 0 && !aRefPad->GetDrillSize().x ) )
1326  {
1327  continue;
1328  }
1329 
1330  if( !checkClearancePadToPad( aRefPad, pad ) )
1331  {
1332  // here we have a drc error!
1334  return false;
1335  }
1336  }
1337 
1338  return true;
1339 }
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:676
int GetNetCode() const
Function GetNetCode.
#define DRCE_PAD_NEAR_PAD1
pad too close to pad
Definition: drc.h:64
#define DRCE_HOLE_NEAR_PAD
hole too close to pad
Definition: drc.h:70
bool PadNameEqual(const D_PAD *other) const
Definition: class_pad.h:212
void SetPosition(const wxPoint &aPos) override
Definition: class_pad.h:224
BOARD * m_pcb
Definition: drc.h:237
Class LSET is a set of PCB_LAYER_IDs.
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:412
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
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:426
MODULE * GetParent() const
Definition: class_pad.h:167
bool checkClearancePadToPad(D_PAD *aRefPad, D_PAD *aPad)
MARKER_PCB * m_currentMarker
Definition: drc.h:211
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:406
const wxSize & GetDrillSize() const
Definition: class_pad.h:290
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
const wxPoint GetPosition() const override
Definition: class_pad.h:225
void SetPosition(const wxPoint &aPos) override

References LSET::AllCuMask(), checkClearancePadToPad(), DRCE_HOLE_NEAR_PAD, DRCE_PAD_NEAR_PAD1, 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_markerFactory, m_pcb, DRC_MARKER_FACTORY::NewMarker(), 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(), and D_PAD::SetSize().

Referenced by testPad2Pad().

◆ doTrackDrc()

bool DRC::doTrackDrc ( TRACK aRefSeg,
TRACKS::iterator  aStartIt,
TRACKS::iterator  aEndIt,
bool  aTestZones 
)
private

Test the current segment.

Parameters
aRefSegThe segment to test
aStartItthe iterator to the first track to test
aEndItthe marker for the iterator end
aTestZonestrue if should do copper zones test. This can be very time consumming
Returns
bool - true if no problems, else false and m_currentMarker is filled in with the problem information.

Definition at line 113 of file drc_clearance_test_functions.cpp.

115 {
116  TRACK* track;
117  wxPoint delta; // length on X and Y axis of segments
118  wxPoint shape_pos;
119 
120  std::vector<MARKER_PCB*> markers;
121 
122  auto commitMarkers = [&]()
123  {
124  BOARD_COMMIT commit( m_pcbEditorFrame );
125 
126  for( MARKER_PCB* marker : markers )
127  commit.Add( marker );
128 
129  commit.Push( wxEmptyString, false, false );
130  };
131 
132  // Returns false if we should return false from call site, or true to continue
133  auto handleNewMarker = [&]() -> bool
134  {
136  {
137  if( markers.size() > 0 )
138  commitMarkers();
139 
140  return false;
141  }
142  else
143  return true;
144  };
145 
146  NETCLASSPTR netclass = aRefSeg->GetNetClass();
148 
149  /* In order to make some calculations more easier or faster,
150  * pads and tracks coordinates will be made relative to the reference segment origin
151  */
152  wxPoint origin = aRefSeg->GetStart(); // origin will be the origin of other coordinates
153 
154  m_segmEnd = delta = aRefSeg->GetEnd() - origin;
155  m_segmAngle = 0;
156 
157  LSET layerMask = aRefSeg->GetLayerSet();
158  int net_code_ref = aRefSeg->GetNetCode();
159  int ref_seg_clearance = netclass->GetClearance();
160  int ref_seg_width = aRefSeg->GetWidth();
161 
162 
163  /******************************************/
164  /* Phase 0 : via DRC tests : */
165  /******************************************/
166 
167  if( aRefSeg->Type() == PCB_VIA_T )
168  {
169  VIA *refvia = static_cast<VIA*>( aRefSeg );
170  wxPoint refviaPos = refvia->GetPosition();
171 
172  // test if the via size is smaller than minimum
173  if( refvia->GetViaType() == VIA_MICROVIA )
174  {
175  if( refvia->GetWidth() < dsnSettings.m_MicroViasMinSize )
176  {
177  markers.PUSH_NEW_MARKER_3( refviaPos, refvia, DRCE_TOO_SMALL_MICROVIA );
178 
179  if( !handleNewMarker() )
180  return false;
181  }
182 
183  if( refvia->GetDrillValue() < dsnSettings.m_MicroViasMinDrill )
184  {
185  markers.PUSH_NEW_MARKER_3( refviaPos, refvia, DRCE_TOO_SMALL_MICROVIA_DRILL );
186 
187  if( !handleNewMarker() )
188  return false;
189  }
190  }
191  else
192  {
193  if( refvia->GetWidth() < dsnSettings.m_ViasMinSize )
194  {
195  markers.PUSH_NEW_MARKER_3( refviaPos, refvia, DRCE_TOO_SMALL_VIA );
196 
197  if( !handleNewMarker() )
198  return false;
199  }
200 
201  if( refvia->GetDrillValue() < dsnSettings.m_ViasMinDrill )
202  {
203  markers.PUSH_NEW_MARKER_3( refviaPos, refvia, DRCE_TOO_SMALL_VIA_DRILL );
204 
205  if( !handleNewMarker() )
206  return false;
207  }
208  }
209 
210  // test if via's hole is bigger than its diameter
211  // This test is necessary since the via hole size and width can be modified
212  // and a default via hole can be bigger than some vias sizes
213  if( refvia->GetDrillValue() > refvia->GetWidth() )
214  {
215  markers.PUSH_NEW_MARKER_3( refviaPos, refvia, DRCE_VIA_HOLE_BIGGER );
216 
217  if( !handleNewMarker() )
218  return false;
219  }
220 
221  // test if the type of via is allowed due to design rules
222  if( refvia->GetViaType() == VIA_MICROVIA && !dsnSettings.m_MicroViasAllowed )
223  {
224  markers.PUSH_NEW_MARKER_3( refviaPos, refvia, DRCE_MICRO_VIA_NOT_ALLOWED );
225 
226  if( !handleNewMarker() )
227  return false;
228  }
229 
230  // test if the type of via is allowed due to design rules
231  if( refvia->GetViaType() == VIA_BLIND_BURIED && !dsnSettings.m_BlindBuriedViaAllowed )
232  {
233  markers.PUSH_NEW_MARKER_3( refviaPos, refvia, DRCE_BURIED_VIA_NOT_ALLOWED );
234 
235  if( !handleNewMarker() )
236  return false;
237  }
238 
239  // For microvias: test if they are blind vias and only between 2 layers
240  // because they are used for very small drill size and are drill by laser
241  // and **only one layer** can be drilled
242  if( refvia->GetViaType() == VIA_MICROVIA )
243  {
244  PCB_LAYER_ID layer1, layer2;
245  bool err = true;
246 
247  refvia->LayerPair( &layer1, &layer2 );
248 
249  if( layer1 > layer2 )
250  std::swap( layer1, layer2 );
251 
252  if( layer2 == B_Cu && layer1 == dsnSettings.GetCopperLayerCount() - 2 )
253  err = false;
254  else if( layer1 == F_Cu && layer2 == In1_Cu )
255  err = false;
256 
257  if( err )
258  {
259  markers.PUSH_NEW_MARKER_3( refviaPos, refvia, DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR );
260 
261  if( !handleNewMarker() )
262  return false;
263  }
264  }
265 
266  }
267  else // This is a track segment
268  {
269  if( ref_seg_width < dsnSettings.m_TrackMinWidth )
270  {
271  wxPoint refsegMiddle = ( aRefSeg->GetStart() + aRefSeg->GetEnd() ) / 2;
272 
273  markers.PUSH_NEW_MARKER_3( refsegMiddle, aRefSeg, DRCE_TOO_SMALL_TRACK_WIDTH );
274 
275  if( !handleNewMarker() )
276  return false;
277  }
278  }
279 
280  // for a non horizontal or vertical segment Compute the segment angle
281  // in tenths of degrees and its length
282  if( delta.x || delta.y )
283  {
284  // Compute the segment angle in 0,1 degrees
285  m_segmAngle = ArcTangente( delta.y, delta.x );
286 
287  // Compute the segment length: we build an equivalent rotated segment,
288  // this segment is horizontal, therefore dx = length
289  RotatePoint( &delta, m_segmAngle ); // delta.x = length, delta.y = 0
290  }
291 
292  m_segmLength = delta.x;
293 
294  /******************************************/
295  /* Phase 1 : test DRC track to pads : */
296  /******************************************/
297 
298  /* Use a dummy pad to test DRC tracks versus holes, for pads not on all copper layers
299  * but having a hole
300  * This dummy pad has the size and shape of the hole
301  * to test tracks to pad hole DRC, using checkClearanceSegmToPad test function.
302  * Therefore, this dummy pad is a circle or an oval.
303  * A pad must have a parent because some functions expect a non null parent
304  * to find the parent board, and some other data
305  */
306  MODULE dummymodule( m_pcb ); // Creates a dummy parent
307  D_PAD dummypad( &dummymodule );
308 
309  dummypad.SetLayerSet( LSET::AllCuMask() ); // Ensure the hole is on all layers
310 
311  // Compute the min distance to pads
312  for( MODULE* mod : m_pcb->Modules() )
313  {
314  for( D_PAD* pad : mod->Pads() )
315  {
316  SEG padSeg( pad->GetPosition(), pad->GetPosition() );
317 
318  // No problem if pads are on another layer, but if a drill hole exists (a pad on
319  // a single layer can have a hole!) we must test the hole
320  if( !( pad->GetLayerSet() & layerMask ).any() )
321  {
322  // We must test the pad hole. In order to use checkClearanceSegmToPad(), a
323  // pseudo pad is used, with a shape and a size like the hole
324  if( pad->GetDrillSize().x == 0 )
325  continue;
326 
327  dummypad.SetSize( pad->GetDrillSize() );
328  dummypad.SetPosition( pad->GetPosition() );
329  dummypad.SetShape( pad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG ?
331  dummypad.SetOrientation( pad->GetOrientation() );
332 
333  m_padToTestPos = dummypad.GetPosition() - origin;
334 
335  if( !checkClearanceSegmToPad( &dummypad, ref_seg_width, ref_seg_clearance ) )
336  {
337  markers.PUSH_NEW_MARKER_4( aRefSeg, pad, padSeg, DRCE_TRACK_NEAR_THROUGH_HOLE );
338 
339  if( !handleNewMarker() )
340  return false;
341  }
342 
343  continue;
344  }
345 
346  // The pad must be in a net (i.e pt_pad->GetNet() != 0 )
347  // but no problem if the pad netcode is the current netcode (same net)
348  if( pad->GetNetCode() // the pad must be connected
349  && net_code_ref == pad->GetNetCode() ) // the pad net is the same as current net -> Ok
350  continue;
351 
352  // DRC for the pad
353  shape_pos = pad->ShapePos();
354  m_padToTestPos = shape_pos - origin;
355  int segToPadClearance = std::max( ref_seg_clearance, pad->GetClearance() );
356 
357  if( !checkClearanceSegmToPad( pad, ref_seg_width, segToPadClearance ) )
358  {
359  markers.PUSH_NEW_MARKER_4( aRefSeg, pad, padSeg, DRCE_TRACK_NEAR_PAD );
360 
361  if( !handleNewMarker() )
362  return false;
363  }
364  }
365  }
366 
367  /***********************************************/
368  /* Phase 2: test DRC with other track segments */
369  /***********************************************/
370 
371  // At this point the reference segment is the X axis
372 
373  // Test the reference segment with other track segments
374  wxPoint segStartPoint;
375  wxPoint segEndPoint;
376 
377  for( auto it = aStartIt; it != aEndIt; it++ )
378  {
379  track = *it;
380  // No problem if segments have the same net code:
381  if( net_code_ref == track->GetNetCode() )
382  continue;
383 
384  // No problem if segment are on different layers :
385  if( !( layerMask & track->GetLayerSet() ).any() )
386  continue;
387 
388  // the minimum distance = clearance plus half the reference track
389  // width plus half the other track's width
390  int w_dist = std::max( ref_seg_clearance, track->GetClearance() );
391  w_dist += ( ref_seg_width + track->GetWidth() ) / 2;
392 
393  // Due to many double to int conversions during calculations, which
394  // create rounding issues,
395  // the exact clearance margin cannot be really known.
396  // To avoid false bad DRC detection due to these rounding issues,
397  // slightly decrease the w_dist (remove one nanometer is enough !)
398  w_dist -= 1;
399 
400  // If the reference segment is a via, we test it here
401  if( aRefSeg->Type() == PCB_VIA_T )
402  {
403  delta = track->GetEnd() - track->GetStart();
404  segStartPoint = aRefSeg->GetStart() - track->GetStart();
405  wxPoint pos = aRefSeg->GetPosition();
406 
407  if( track->Type() == PCB_VIA_T )
408  {
409  // Test distance between two vias, i.e. two circles, trivial case
410  if( EuclideanNorm( segStartPoint ) < w_dist )
411  {
412  markers.PUSH_NEW_MARKER_4( pos, aRefSeg, track, DRCE_VIA_NEAR_VIA );
413 
414  if( !handleNewMarker() )
415  return false;
416  }
417  }
418  else // test via to segment
419  {
420  // Compute l'angle du segment a tester;
421  double angle = ArcTangente( delta.y, delta.x );
422 
423  // Compute new coordinates ( the segment become horizontal)
424  RotatePoint( &delta, angle );
425  RotatePoint( &segStartPoint, angle );
426 
427  if( !checkMarginToCircle( segStartPoint, w_dist, delta.x ) )
428  {
429  markers.PUSH_NEW_MARKER_4( pos, aRefSeg, track, DRCE_VIA_NEAR_TRACK );
430 
431  if( !handleNewMarker() )
432  return false;
433  }
434  }
435 
436  continue;
437  }
438 
439  /* We compute segStartPoint, segEndPoint = starting and ending point coordinates for
440  * the segment to test in the new axis : the new X axis is the
441  * reference segment. We must translate and rotate the segment to test
442  */
443  segStartPoint = track->GetStart() - origin;
444  segEndPoint = track->GetEnd() - origin;
445  RotatePoint( &segStartPoint, m_segmAngle );
446  RotatePoint( &segEndPoint, m_segmAngle );
447 
448  SEG seg( segStartPoint, segEndPoint );
449 
450  if( track->Type() == PCB_VIA_T )
451  {
452  if( checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
453  continue;
454 
455  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_TRACK_NEAR_VIA );
456 
457  if( !handleNewMarker() )
458  return false;
459  }
460 
461  /* We have changed axis:
462  * the reference segment is Horizontal.
463  * 3 cases : the segment to test can be parallel, perpendicular or have another direction
464  */
465  if( segStartPoint.y == segEndPoint.y ) // parallel segments
466  {
467  if( abs( segStartPoint.y ) >= w_dist )
468  continue;
469 
470  // Ensure segStartPoint.x <= segEndPoint.x
471  if( segStartPoint.x > segEndPoint.x )
472  std::swap( segStartPoint.x, segEndPoint.x );
473 
474  if( segStartPoint.x > ( -w_dist ) && segStartPoint.x < ( m_segmLength + w_dist ) )
475  {
476  // the start point is inside the reference range
477  // X........
478  // O--REF--+
479 
480  // Fine test : we consider the rounded shape of each end of the track segment:
481  if( segStartPoint.x >= 0 && segStartPoint.x <= m_segmLength )
482  {
483  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_TRACK_ENDS1 );
484 
485  if( !handleNewMarker() )
486  return false;
487  }
488 
489  if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
490  {
491  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_TRACK_ENDS2 );
492 
493  if( !handleNewMarker() )
494  return false;
495  }
496  }
497 
498  if( segEndPoint.x > ( -w_dist ) && segEndPoint.x < ( m_segmLength + w_dist ) )
499  {
500  // the end point is inside the reference range
501  // .....X
502  // O--REF--+
503  // Fine test : we consider the rounded shape of the ends
504  if( segEndPoint.x >= 0 && segEndPoint.x <= m_segmLength )
505  {
506  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_TRACK_ENDS3 );
507 
508  if( !handleNewMarker() )
509  return false;
510  }
511 
512  if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
513  {
514  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_TRACK_ENDS4 );
515 
516  if( !handleNewMarker() )
517  return false;
518  }
519  }
520 
521  if( segStartPoint.x <= 0 && segEndPoint.x >= 0 )
522  {
523  // the segment straddles the reference range (this actually only
524  // checks if it straddles the origin, because the other cases where already
525  // handled)
526  // X.............X
527  // O--REF--+
528  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_TRACK_SEGMENTS_TOO_CLOSE );
529 
530  if( !handleNewMarker() )
531  return false;
532  }
533  }
534  else if( segStartPoint.x == segEndPoint.x ) // perpendicular segments
535  {
536  if( segStartPoint.x <= -w_dist || segStartPoint.x >= m_segmLength + w_dist )
537  continue;
538 
539  // Test if segments are crossing
540  if( segStartPoint.y > segEndPoint.y )
541  std::swap( segStartPoint.y, segEndPoint.y );
542 
543  if( ( segStartPoint.y < 0 ) && ( segEndPoint.y > 0 ) )
544  {
545  MARKER_PCB* m = m_markerFactory.NewMarker( aRefSeg, track, seg,
547  m->SetPosition( wxPoint( track->GetStart().x, aRefSeg->GetStart().y ) );
548  markers.push_back( m );
549 
550  if( !handleNewMarker() )
551  return false;
552  }
553 
554  // At this point the drc error is due to an end near a reference segm end
555  if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
556  {
557  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_ENDS_PROBLEM1 );
558 
559  if( !handleNewMarker() )
560  return false;
561  }
562  if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
563  {
564  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_ENDS_PROBLEM2 );
565 
566  if( !handleNewMarker() )
567  return false;
568  }
569  }
570  else // segments quelconques entre eux
571  {
572  // calcul de la "surface de securite du segment de reference
573  // First rought 'and fast) test : the track segment is like a rectangle
574 
575  m_xcliplo = m_ycliplo = -w_dist;
576  m_xcliphi = m_segmLength + w_dist;
577  m_ycliphi = w_dist;
578 
579  // A fine test is needed because a serment is not exactly a
580  // rectangle, it has rounded ends
581  if( !checkLine( segStartPoint, segEndPoint ) )
582  {
583  /* 2eme passe : the track has rounded ends.
584  * we must a fine test for each rounded end and the
585  * rectangular zone
586  */
587 
588  m_xcliplo = 0;
590 
591  if( !checkLine( segStartPoint, segEndPoint ) )
592  {
593  wxPoint failurePoint;
594  MARKER_PCB* m;
595 
596  if( SegmentIntersectsSegment( aRefSeg->GetStart(), aRefSeg->GetEnd(),
597  track->GetStart(), track->GetEnd(),
598  &failurePoint ) )
599  {
600  m = m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_TRACKS_CROSSING );
601  m->SetPosition( failurePoint );
602  }
603  else
604  {
605  m = m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM3 );
606  }
607 
608  markers.push_back( m );
609 
610  if( !handleNewMarker() )
611  return false;
612  }
613  else // The drc error is due to the starting or the ending point of the reference segment
614  {
615  // Test the starting and the ending point
616  segStartPoint = track->GetStart();
617  segEndPoint = track->GetEnd();
618  delta = segEndPoint - segStartPoint;
619 
620  // Compute the segment orientation (angle) en 0,1 degre
621  double angle = ArcTangente( delta.y, delta.x );
622 
623  // Compute the segment length: delta.x = length after rotation
624  RotatePoint( &delta, angle );
625 
626  /* Comute the reference segment coordinates relatives to a
627  * X axis = current tested segment
628  */
629  wxPoint relStartPos = aRefSeg->GetStart() - segStartPoint;
630  wxPoint relEndPos = aRefSeg->GetEnd() - segStartPoint;
631 
632  RotatePoint( &relStartPos, angle );
633  RotatePoint( &relEndPos, angle );
634 
635  if( !checkMarginToCircle( relStartPos, w_dist, delta.x ) )
636  {
637  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_ENDS_PROBLEM4 );
638 
639  if( !handleNewMarker() )
640  return false;
641  }
642 
643  if( !checkMarginToCircle( relEndPos, w_dist, delta.x ) )
644  {
645  markers.PUSH_NEW_MARKER_4( aRefSeg, track, seg, DRCE_ENDS_PROBLEM5 );
646 
647  if( !handleNewMarker() )
648  return false;
649  }
650  }
651  }
652  }
653  }
654 
655  /***************************************/
656  /* Phase 3: test DRC with copper zones */
657  /***************************************/
658  // Can be *very* time consumming.
659  if( aTestZones )
660  {
661  SEG refSeg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
662 
663  for( ZONE_CONTAINER* zone : m_pcb->Zones() )
664  {
665  if( zone->GetFilledPolysList().IsEmpty() || zone->GetIsKeepout() )
666  continue;
667 
668  if( !( layerMask & zone->GetLayerSet() ).any() )
669  continue;
670 
671  if( zone->GetNetCode() && zone->GetNetCode() == net_code_ref )
672  continue;
673 
674  int clearance = std::max( ref_seg_clearance, zone->GetClearance() );
675  SHAPE_POLY_SET* outline = const_cast<SHAPE_POLY_SET*>( &zone->GetFilledPolysList() );
676 
677  if( outline->Distance( refSeg, ref_seg_width ) < clearance )
679  }
680  }
681 
682  /***********************************************/
683  /* Phase 4: test DRC with to board edge */
684  /***********************************************/
685  {
686  SEG test_seg( aRefSeg->GetStart(), aRefSeg->GetEnd() );
687 
688  int clearance = std::max( ref_seg_clearance, dsnSettings.m_CopperEdgeClearance );
689 
690  // the minimum distance = clearance plus half the reference track width
691  SEG::ecoord w_dist = clearance + ref_seg_width / 2;
692  SEG::ecoord w_dist_sq = w_dist * w_dist;
693 
694  for( auto it = m_board_outlines.IterateSegmentsWithHoles(); it; it++ )
695  {
696  if( test_seg.SquaredDistance( *it ) < w_dist_sq )
697  {
698  VECTOR2I pt = test_seg.NearestPoint( *it );
699 
700  KICAD_T types[] = { PCB_LINE_T, EOT };
701  DRAWSEGMENT* edge = nullptr;
702  INSPECTOR_FUNC inspector = [&] ( EDA_ITEM* item, void* testData )
703  {
704  DRAWSEGMENT* test_edge = dynamic_cast<DRAWSEGMENT*>( item );
705 
706  if( !test_edge || test_edge->GetLayer() != Edge_Cuts )
707  return SEARCH_CONTINUE;
708 
709  if( test_edge->HitTest((wxPoint) pt, w_dist ) )
710  {
711  edge = test_edge;
712  return SEARCH_QUIT;
713  }
714 
715  return SEARCH_CONTINUE;
716  };
717 
718  // Best-efforts search for edge segment
719  BOARD::IterateForward<BOARD_ITEM*>( m_pcb->Drawings(), inspector, nullptr, types );
720 
721  if( edge )
722  markers.PUSH_NEW_MARKER_4( (wxPoint) pt, aRefSeg, edge, DRCE_TRACK_NEAR_EDGE );
723  else
724  markers.PUSH_NEW_MARKER_3( (wxPoint) pt, aRefSeg, DRCE_TRACK_NEAR_EDGE );
725 
726  if( !handleNewMarker() )
727  return false;
728  }
729  }
730  }
731 
732 
733  if( markers.size() > 0 )
734  {
735  commitMarkers();
736  return false;
737  }
738  else
739  return true;
740 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:123
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:676
#define DRCE_TOO_SMALL_MICROVIA_DRILL
Too small micro via drill.
Definition: drc.h:76
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:57
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...
#define DRCE_TOO_SMALL_VIA
Too small via size.
Definition: drc.h:73
int GetNetCode() const
Function GetNetCode.
std::function< SEARCH_RESULT(EDA_ITEM *aItem, void *aTestData) > INSPECTOR_FUNC
Typedef INSPECTOR is used to inspect and possibly collect the (search) results of iterating over a li...
Definition: base_struct.h:83
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Returns an iterator object, for all outlines in the set (with holes)
int m_ycliplo
Definition: drc.h:232
const wxPoint & GetStart() const
Definition: class_track.h:109
VECTOR2I::extended_type ecoord
Definition: seg.h:39
#define DRCE_TRACK_ENDS4
2 parallel track segments too close: fine end point test
Definition: drc.h:56
int m_ycliphi
Definition: drc.h:234
#define DRCE_TRACK_NEAR_PAD
pad too close to track
Definition: drc.h:49
int m_segmLength
Definition: drc.h:226
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:540
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:206
wxPoint m_padToTestPos
Definition: drc.h:217
#define abs(a)
Definition: auxiliary.h:84
#define DRCE_TRACK_ENDS2
2 parallel track segments too close: fine start point test
Definition: drc.h:54
search types array terminator (End Of Types)
Definition: typeinfo.h:82
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
#define DRCE_TRACK_SEGMENTS_TOO_CLOSE
2 parallel track segments too close: segm ends between segref ends
Definition: drc.h:57
#define DRCE_BURIED_VIA_NOT_ALLOWED
buried vias are not allowed
Definition: drc.h:95
#define DRCE_TRACK_NEAR_VIA
track too close to via
Definition: drc.h:50
BOARD * m_pcb
Definition: drc.h:237
#define DRCE_TOO_SMALL_MICROVIA
Too small micro via size.
Definition: drc.h:74
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_VIA_HOLE_BIGGER
via's hole is bigger than its diameter
Definition: drc.h:65
PCB_LAYER_ID
A quick note on layer IDs:
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
Class LSET is a set of PCB_LAYER_IDs.
const wxPoint GetPosition() const override
Definition: class_track.h:100
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:160
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
MODULES & Modules()
Definition: class_board.h:236
#define DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR
micro via's layer pair incorrect (layers must be adjacent)
Definition: drc.h:66
Class SHAPE_POLY_SET.
int m_TrackMinWidth
track min value for width ((min copper size value
#define DRCE_TRACK_ENDS1
2 parallel track segments too close: fine start point test
Definition: drc.h:53
int m_ViasMinSize
vias (not micro vias) min diameter
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
#define DRCE_TRACK_ENDS3
2 parallel track segments too close: fine end point test
Definition: drc.h:55
#define DRCE_ENDS_PROBLEM2
track ends are too close
Definition: drc.h:60
int m_ViasMinDrill
vias (not micro vias) min drill diameter
#define DRCE_TRACK_NEAR_ZONE
track & zone collide or are too close together
Definition: drc.h:89
#define DRCE_ENDS_PROBLEM3
track ends are too close
Definition: drc.h:61
VIATYPE_T GetViaType() const
Definition: class_track.h:346
static bool checkMarginToCircle(wxPoint aCentre, int aRadius, int aLength)
Check the distance from a point to a segment.
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
bool m_reportAllTrackErrors
Definition: drc.h:206
virtual int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
int m_xcliphi
Definition: drc.h:233
int m_MicroViasMinSize
micro vias (not vias) min diameter
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:236
string & err
Definition: json11.cpp:598
const wxPoint GetPosition() const override
Definition: class_track.h:319
#define DRCE_ENDS_PROBLEM4
track ends are too close
Definition: drc.h:62
Definition: seg.h:36
#define DRCE_VIA_NEAR_VIA
via too close to via
Definition: drc.h:51
#define DRCE_TRACKS_CROSSING
tracks are crossing
Definition: drc.h:58
bool checkClearanceSegmToPad(const D_PAD *aPad, int aSegmentWidth, int aMinDist)
Check the distance from a pad to segment.
#define DRCE_ENDS_PROBLEM5
track ends are too close
Definition: drc.h:63
wxPoint m_segmEnd
Definition: drc.h:218
SHAPE_POLY_SET m_board_outlines
The board outline including cutouts.
Definition: drc.h:238
ZONE_CONTAINERS & Zones()
Definition: class_board.h:250
int GetWidth() const
Definition: class_track.h:103
#define max(a, b)
Definition: auxiliary.h:86
std::shared_ptr< NETCLASS > GetNetClass() const
Function GetNetClass returns the NETCLASS for this item.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
#define DRCE_VIA_NEAR_TRACK
via too close to track
Definition: drc.h:52
bool SegmentIntersectsSegment(const wxPoint &a_p1_l1, const wxPoint &a_p2_l1, const wxPoint &a_p1_l2, const wxPoint &a_p2_l2, wxPoint *aIntersectionPoint)
Function SegmentIntersectsSegment.
Definition: trigo.cpp:59
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:163
const wxPoint & GetEnd() const
Definition: class_track.h:106
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
#define DRCE_TRACK_NEAR_EDGE
track too close to board edge
Definition: drc.h:98
bool m_MicroViasAllowed
true to allow micro vias
#define DRCE_MICRO_VIA_NOT_ALLOWED
micro vias are not allowed
Definition: drc.h:94
int m_MicroViasMinDrill
micro vias (not vias) min drill diameter
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
int m_xcliplo
Definition: drc.h:231
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
int GetCopperLayerCount() const
Function GetCopperLayerCount.
#define DRCE_ENDS_PROBLEM1
track ends are too close
Definition: drc.h:59
DRAWINGS & Drawings()
Definition: class_board.h:245
#define mod(a, n)
Definition: greymap.cpp:24
#define DRCE_TOO_SMALL_VIA_DRILL
Too small via drill.
Definition: drc.h:75
#define DRCE_TRACK_NEAR_THROUGH_HOLE
thru hole is too close to track
Definition: drc.h:48
double m_segmAngle
Definition: drc.h:225
void SetPosition(const wxPoint &aPos) override
virtual LSET GetLayerSet() const
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
KICAD_T Type() const
Function Type()
Definition: base_struct.h:210
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
#define DRCE_TOO_SMALL_TRACK_WIDTH
Too small track width.
Definition: drc.h:72

References abs, COMMIT::Add(), addMarkerToPcb(), LSET::AllCuMask(), PNS::angle(), ArcTangente(), B_Cu, checkClearanceSegmToPad(), checkLine(), checkMarginToCircle(), BOARD::Drawings(), 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_EDGE, DRCE_TRACK_NEAR_PAD, DRCE_TRACK_NEAR_THROUGH_HOLE, DRCE_TRACK_NEAR_VIA, DRCE_TRACK_NEAR_ZONE, DRCE_TRACK_SEGMENTS_TOO_CLOSE, DRCE_TRACKS_CROSSING, DRCE_VIA_HOLE_BIGGER, DRCE_VIA_NEAR_TRACK, DRCE_VIA_NEAR_VIA, Edge_Cuts, EOT, err, EuclideanNorm(), F_Cu, TRACK::GetClearance(), BOARD_DESIGN_SETTINGS::GetCopperLayerCount(), BOARD::GetDesignSettings(), VIA::GetDrillValue(), TRACK::GetEnd(), BOARD_ITEM::GetLayer(), BOARD_ITEM::GetLayerSet(), BOARD_CONNECTED_ITEM::GetNetClass(), BOARD_CONNECTED_ITEM::GetNetCode(), TRACK::GetPosition(), D_PAD::GetPosition(), VIA::GetPosition(), TRACK::GetStart(), VIA::GetViaType(), TRACK::GetWidth(), DRAWSEGMENT::HitTest(), In1_Cu, SHAPE_POLY_SET::IterateSegmentsWithHoles(), VIA::LayerPair(), BOARD_DESIGN_SETTINGS::m_BlindBuriedViaAllowed, m_board_outlines, BOARD_DESIGN_SETTINGS::m_CopperEdgeClearance, m_markerFactory, BOARD_DESIGN_SETTINGS::m_MicroViasAllowed, BOARD_DESIGN_SETTINGS::m_MicroViasMinDrill, BOARD_DESIGN_SETTINGS::m_MicroViasMinSize, m_padToTestPos, m_pcb, m_pcbEditorFrame, m_reportAllTrackErrors, 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, max, mod, BOARD::Modules(), DRC_MARKER_FACTORY::NewMarker(), PAD_DRILL_SHAPE_OBLONG, PAD_SHAPE_CIRCLE, PAD_SHAPE_OVAL, PCB_LINE_T, PCB_VIA_T, BOARD_COMMIT::Push(), RotatePoint(), SEARCH_CONTINUE, SEARCH_QUIT, SegmentIntersectsSegment(), D_PAD::SetLayerSet(), D_PAD::SetOrientation(), MARKER_PCB::SetPosition(), D_PAD::SetPosition(), D_PAD::SetShape(), D_PAD::SetSize(), EDA_ITEM::Type(), VIA_BLIND_BURIED, VIA_MICROVIA, and BOARD::Zones().

Referenced by testTracks().

◆ EditingModules()

bool PCB_TOOL_BASE::EditingModules ( ) const
inlineinherited

◆ frame()

PCB_BASE_EDIT_FRAME* PCB_TOOL_BASE::frame ( ) const
inlineprotectedinherited

Definition at line 146 of file pcb_tool_base.h.

147  {
148  return getEditFrame<PCB_BASE_EDIT_FRAME>();
149  }

Referenced by POINT_EDITOR::addCorner(), MICROWAVE_TOOL::addMicrowaveFootprint(), AUTOPLACE_TOOL::autoplace(), PCB_TOOL_BASE::canvas(), EDIT_TOOL::changeTrackWidthOnClick(), ZONE_FILLER_TOOL::CheckAllZones(), PNS::TOOL_BASE::checkSnap(), PAD_TOOL::copyPadSettings(), EDIT_TOOL::copyToClipboard(), MICROWAVE_TOOL::createInductorBetween(), ROUTER_TOOL::CustomTrackWidthDialog(), MODULE_EDITOR_TOOLS::DeleteFootprint(), PCB_TOOL_BASE::displayOptions(), PCB_TOOL_BASE::doInteractiveItemPlacement(), ROUTER_TOOL::DpDimensionsDialog(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::drawSegment(), DRAWING_TOOL::DrawVia(), DRAWING_TOOL::DrawZone(), PAD_TOOL::EnumeratePads(), PCB_EDITOR_CONTROL::ExportSpecctraDSN(), ROUTER_TOOL::finishInteractive(), EDIT_TOOL::Flip(), PCB_EDITOR_CONTROL::FlipPcbView(), GLOBAL_EDIT_TOOL::GlobalDeletions(), MODULE_EDITOR_TOOLS::ImportFootprint(), PCB_EDITOR_CONTROL::ImportSpecctraSession(), SELECTION_TOOL::Init(), EDIT_TOOL::Init(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), PCBNEW_PICKER_TOOL::Main(), ROUTER_TOOL::MainLoop(), LENGTH_TUNER_TOOL::MainLoop(), LENGTH_TUNER_TOOL::meanderSettingsDialog(), EDIT_TOOL::MeasureTool(), EDIT_TOOL::Move(), POINT_EDITOR::OnSelectionChange(), ROUTER_TOOL::onViaCommand(), PCBNEW_CONTROL::Paste(), PAD_TOOL::pastePadProperties(), ROUTER_TOOL::performDragging(), ROUTER_TOOL::performRouting(), LENGTH_TUNER_TOOL::performTuning(), EDIT_TOOL::pickCopyReferencePoint(), PCB_EDITOR_CONTROL::PlaceModule(), PCB_EDITOR_CONTROL::PlaceTarget(), DRAWING_TOOL::PlaceText(), ROUTER_TOOL::prepareInteractive(), PAD_TOOL::pushPadSettings(), POSITION_RELATIVE_TOOL::RelativeItemSelectionMove(), EDIT_TOOL::Remove(), POINT_EDITOR::removeCorner(), PNS::TOOL_BASE::Reset(), ROUTER_TOOL::SelectCopperLayerPair(), POSITION_RELATIVE_TOOL::SelectPositionRelativeItem(), POINT_EDITOR::setEditedPoint(), ROUTER_TOOL::SettingsDialog(), GLOBAL_EDIT_TOOL::swapBoardItem(), GLOBAL_EDIT_TOOL::SwapLayers(), ROUTER_TOOL::switchLayerOnViaPlacement(), POINT_EDITOR::updateItem(), ZONE_FILLER_TOOL::ZoneFill(), and ZONE_FILLER_TOOL::ZoneFillAll().

◆ getEditFrame()

template<typename T >
T* TOOL_BASE::getEditFrame ( ) const
inlineprotectedinherited

Function getEditFrame()

Returns the application window object, casted to requested user type.

Definition at line 187 of file tool_base.h.

188  {
189 #if !defined( QA_TEST ) // Dynamic casts give the linker a siezure in the test framework
190  wxASSERT( dynamic_cast<T*>( getEditFrameInt() ) );
191 #endif
192  return static_cast<T*>( getEditFrameInt() );
193  }
EDA_BASE_FRAME * getEditFrameInt() const
Definition: tool_base.cpp:48

References TOOL_BASE::getEditFrameInt().

Referenced by ZONE_CREATE_HELPER::createNewZone(), and TOOL_SETTINGS::getConfigBase().

◆ GetId()

TOOL_ID TOOL_BASE::GetId ( ) const
inlineinherited

Function GetId() Returns the unique identifier of the tool.

The identifier is set by an instance of TOOL_MANAGER.

Returns
Identifier of the tool.

Definition at line 121 of file tool_base.h.

122  {
123  return m_toolId;
124  }
TOOL_ID m_toolId
Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
Definition: tool_base.h:214

References TOOL_BASE::m_toolId.

Referenced by TOOL_MANAGER::finishTool(), TOOL_MANAGER::InitTools(), TOOL_MANAGER::isActive(), TOOL_MANAGER::RegisterTool(), ACTION_MANAGER::RunHotKey(), TOOL_MANAGER::runTool(), and TOOL_MANAGER::saveViewControls().

◆ GetManager()

TOOL_MANAGER* TOOL_BASE::GetManager ( ) const
inlineinherited

Function GetManager() Returns the instance of TOOL_MANAGER that takes care of the tool.

Returns
Instance of the TOOL_MANAGER. If there is no TOOL_MANAGER associated, it returns NULL.

Definition at line 143 of file tool_base.h.

144  {
145  return m_toolMgr;
146  }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219

References TOOL_BASE::m_toolMgr.

Referenced by BOARD_COMMIT::BOARD_COMMIT(), ZONE_CREATE_HELPER::commitZone(), ZONE_CREATE_HELPER::createNewZone(), PCB_TOOL_BASE::doInteractiveItemPlacement(), ACTION_MENU::getToolManager(), LIB_TREE::onContextMenu(), ZONE_CREATE_HELPER::OnFirstPoint(), ACTION_MENU::OnMenuEvent(), and ZONE_CREATE_HELPER::performZoneCutout().

◆ getModel()

template<typename T >
T* TOOL_BASE::getModel ( ) const
inlineprotectedinherited

Function getModel()

Returns the model object if it matches the requested type.

Definition at line 201 of file tool_base.h.

202  {
203  EDA_ITEM* m = getModelInt();
204 #if !defined( QA_TEST ) // Dynamic casts give the linker a siezure in the test framework
205  wxASSERT( dynamic_cast<T*>( m ) );
206 #endif
207  return static_cast<T*>( m );
208  }
EDA_ITEM * getModelInt() const
Definition: tool_base.cpp:54
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:163

References TOOL_BASE::getModelInt().

Referenced by ZONE_CREATE_HELPER::commitZone(), ZONE_CREATE_HELPER::createNewZone(), ZONE_CREATE_HELPER::createZoneFromExisting(), and ZONE_CREATE_HELPER::performZoneCutout().

◆ GetName()

const std::string& TOOL_BASE::GetName ( void  ) const
inlineinherited

Function GetName() Returns the name of the tool.

Tool names are expected to obey the format: application.ToolName (eg. pcbnew.InteractiveSelection).

Returns
The name of the tool.

Definition at line 132 of file tool_base.h.

133  {
134  return m_toolName;
135  }
std::string m_toolName
Name of the tool.
Definition: tool_base.h:218

References TOOL_BASE::m_toolName.

Referenced by TOOL_MANAGER::dispatchInternal(), TOOL_SETTINGS::getKeyName(), TOOL_MANAGER::InitTools(), TOOL_MANAGER::invokeTool(), and TOOL_MANAGER::RegisterTool().

◆ GetSettings()

TOOL_SETTINGS & TOOL_BASE::GetSettings ( )
inherited

Definition at line 78 of file tool_base.cpp.

79 {
80  return m_toolSettings;
81 }
TOOL_SETTINGS m_toolSettings
Definition: tool_base.h:220

References TOOL_BASE::m_toolSettings.

Referenced by ROUTER_TOOL::Init(), GERBVIEW_SELECTION_TOOL::selectable(), and ROUTER_TOOL::~ROUTER_TOOL().

◆ GetToolMenu()

◆ GetType()

TOOL_TYPE TOOL_BASE::GetType ( ) const
inlineinherited

Function GetType() Returns the type of the tool.

Returns
The type of the tool.

Definition at line 110 of file tool_base.h.

111  {
112  return m_type;
113  }
TOOL_TYPE m_type
Stores the type of the tool.
Definition: tool_base.h:211

References TOOL_BASE::m_type.

Referenced by TOOL_MANAGER::finishTool(), TOOL_MANAGER::InvokeTool(), TOOL_MANAGER::ResetTools(), and TOOL_MANAGER::runTool().

◆ getView()

KIGFX::VIEW * TOOL_BASE::getView ( ) const
protectedinherited

Function getView()

Returns the instance of VIEW object used in the application. It allows tools to draw.

Returns
The instance of VIEW.

Definition at line 36 of file tool_base.cpp.

37 {
38  return m_toolMgr->GetView();
39 }
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:241
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219

References TOOL_MANAGER::GetView(), and TOOL_BASE::m_toolMgr.

Referenced by EE_POINT_EDITOR::addCornerCondition(), ALIGN_DISTRIBUTE_TOOL::AlignLeft(), ALIGN_DISTRIBUTE_TOOL::AlignRight(), COMMON_TOOLS::CenterContents(), PL_SELECTION_TOOL::ClearSelection(), EE_SELECTION_TOOL::ClearSelection(), COMMON_TOOLS::CursorControl(), LIB_EDIT_TOOL::DeleteItemCursor(), PL_EDIT_TOOL::DeleteItemCursor(), SCH_EDIT_TOOL::DeleteItemCursor(), PCBNEW_CONTROL::DeleteItemCursor(), GERBVIEW_SELECTION_TOOL::disambiguationMenu(), PL_EDIT_TOOL::DoDelete(), PL_SELECTION_TOOL::doSelectionMenu(), EE_SELECTION_TOOL::doSelectionMenu(), SELECTION_TOOL::doSelectionMenu(), MICROWAVE_TOOL::drawMicrowaveInductor(), PL_DRAWING_TOOLS::DrawShape(), PCB_EDITOR_CONTROL::DrillOrigin(), LIB_EDIT_TOOL::Duplicate(), PAD_TOOL::EnumeratePads(), EE_SELECTION_TOOL::GetNode(), ROUTER_TOOL::getStartLayer(), COMMON_TOOLS::GridPreset(), PCBNEW_CONTROL::GridResetOrigin(), PCBNEW_CONTROL::GridSetOrigin(), SELECTION_TOOL::GuessSelectionCandidates(), PL_SELECTION_TOOL::highlight(), EE_SELECTION_TOOL::highlight(), SELECTION_TOOL::highlight(), GERBVIEW_CONTROL::HighlightControl(), PNS::TOOL_BASE::highlightNet(), PCB_INSPECTION_TOOL::highlightNet(), EE_POINT_EDITOR::Main(), PL_POINT_EDITOR::Main(), CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::MeasureTool(), GERBVIEW_SELECTION_TOOL::MeasureTool(), EDIT_TOOL::MeasureTool(), SCH_EDIT_TOOL::Mirror(), EDIT_TOOL::MoveExact(), SCH_MOVE_TOOL::moveItem(), PL_EDIT_TOOL::moveItem(), POINT_EDITOR::OnSelectionChange(), COMMON_TOOLS::PanControl(), LIB_EDIT_TOOL::Paste(), PL_EDIT_TOOL::Paste(), SCH_EDITOR_CONTROL::Paste(), PNS::TOOL_BASE::pickSingleItem(), PL_DRAWING_TOOLS::PlaceItem(), PCB_EDITOR_CONTROL::PlaceModule(), PCB_EDITOR_CONTROL::PlaceTarget(), SCH_EDIT_TOOL::Properties(), EDIT_TOOL::Remove(), PCB_EDITOR_CONTROL::Reset(), PNS::TOOL_BASE::Reset(), PCBNEW_CONTROL::Reset(), GERBVIEW_SELECTION_TOOL::Reset(), DRAWING_TOOL::Reset(), EE_SELECTION_TOOL::Reset(), SELECTION_TOOL::Reset(), EE_TOOL_BASE< SCH_BASE_FRAME >::Reset(), SCH_EDIT_TOOL::Rotate(), GERBVIEW_SELECTION_TOOL::select(), SELECTION_TOOL::Selectable(), GERBVIEW_SELECTION_TOOL::selectable(), PL_SELECTION_TOOL::selectionContains(), EE_SELECTION_TOOL::selectionContains(), SELECTION_TOOL::selectionContains(), PL_SELECTION_TOOL::selectMultiple(), EE_SELECTION_TOOL::selectMultiple(), SELECTION_TOOL::selectMultiple(), PL_SELECTION_TOOL::SelectPoint(), EE_SELECTION_TOOL::SelectPoint(), ZOOM_TOOL::selectRegion(), GERBVIEW_SELECTION_TOOL::selectVisually(), PL_EDITOR_CONTROL::ToggleBackgroundColor(), COMMON_TOOLS::ToggleGrid(), SCH_EDITOR_CONTROL::ToggleHiddenPins(), PL_SELECTION_TOOL::unhighlight(), EE_SELECTION_TOOL::unhighlight(), SELECTION_TOOL::unhighlight(), GERBVIEW_SELECTION_TOOL::unselect(), GERBVIEW_SELECTION_TOOL::unselectVisually(), EE_POINT_EDITOR::updateEditedPoint(), PL_POINT_EDITOR::updateEditedPoint(), POINT_EDITOR::updateEditedPoint(), SCH_EDITOR_CONTROL::UpdateFind(), PCBNEW_CONTROL::updateGrid(), EE_POINT_EDITOR::updateItem(), PL_POINT_EDITOR::updateItem(), SCH_EDITOR_CONTROL::UpdateNetHighlighting(), EE_POINT_EDITOR::updatePoints(), PL_POINT_EDITOR::updatePoints(), POINT_EDITOR::updatePoints(), SELECTION_TOOL::updateSelection(), PNS::TOOL_BASE::updateStartItem(), EE_TOOL_BASE< SCH_BASE_FRAME >::updateView(), PCB_TOOL_BASE::view(), COMMON_TOOLS::ZoomFitScreen(), SELECTION_TOOL::zoomFitSelection(), EE_SELECTION_TOOL::~EE_SELECTION_TOOL(), GERBVIEW_SELECTION_TOOL::~GERBVIEW_SELECTION_TOOL(), and SELECTION_TOOL::~SELECTION_TOOL().

◆ getViewControls()

KIGFX::VIEW_CONTROLS * TOOL_BASE::getViewControls ( ) const
protectedinherited

Function getViewControls()

Returns the instance of VIEW_CONTROLS object used in the application. It allows tools to read & modify user input and its settings (eg. show cursor, enable snapping to grid, etc.)

Returns
The instance of VIEW_CONTROLS.

Definition at line 42 of file tool_base.cpp.

43 {
44  return m_toolMgr->GetViewControls();
45 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
KIGFX::VIEW_CONTROLS * GetViewControls() const
Definition: tool_manager.h:246

References TOOL_MANAGER::GetViewControls(), and TOOL_BASE::m_toolMgr.

Referenced by EE_POINT_EDITOR::addCorner(), POINT_EDITOR::addCorner(), EE_POINT_EDITOR::addCornerCondition(), SCH_EDIT_TOOL::BreakWire(), PCB_TOOL_BASE::controls(), COMMON_TOOLS::CursorControl(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), SCH_LINE_WIRE_BUS_TOOL::doUnfoldBus(), COMMON_TOOLS::doZoomToPreset(), DRAWING_TOOL::DrawCircle(), DRAWING_TOOL::DrawLine(), MICROWAVE_TOOL::drawMicrowaveInductor(), SCH_LINE_WIRE_BUS_TOOL::DrawSegments(), LIB_DRAWING_TOOLS::DrawShape(), PL_DRAWING_TOOLS::DrawShape(), SCH_DRAWING_TOOLS::DrawSheet(), LIB_EDIT_TOOL::Duplicate(), PAD_TOOL::EnumeratePads(), SCH_LINE_WIRE_BUS_TOOL::finishSegments(), COMMON_TOOLS::GridPreset(), PCB_INSPECTION_TOOL::HighlightNet(), SCH_EDITOR_CONTROL::HighlightNet(), PCB_INSPECTION_TOOL::HighlightNetTool(), MODULE_EDITOR_TOOLS::ImportFootprint(), PL_EDIT_TOOL::Main(), SCH_MOVE_TOOL::Main(), EE_POINT_EDITOR::Main(), PL_POINT_EDITOR::Main(), LIB_MOVE_TOOL::Main(), CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::Main(), PCBNEW_PICKER_TOOL::Main(), PICKER_TOOL::Main(), GERBVIEW_SELECTION_TOOL::Main(), ROUTER_TOOL::MainLoop(), CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::MeasureTool(), GERBVIEW_SELECTION_TOOL::MeasureTool(), EDIT_TOOL::MeasureTool(), EDIT_TOOL::Move(), POINT_EDITOR::OnSelectionChange(), LIB_EDIT_TOOL::Paste(), ROUTER_TOOL::performDragging(), LIB_DRAWING_TOOLS::PlaceAnchor(), PCBNEW_CONTROL::placeBoardItems(), SCH_DRAWING_TOOLS::PlaceComponent(), SCH_DRAWING_TOOLS::PlaceImage(), PL_DRAWING_TOOLS::PlaceItem(), PCB_EDITOR_CONTROL::PlaceModule(), PCB_EDITOR_CONTROL::PlaceTarget(), SCH_EDIT_TOOL::RepeatDrawItem(), PL_SELECTION_TOOL::RequestSelection(), EE_SELECTION_TOOL::RequestSelection(), POINT_EDITOR::Reset(), DRAWING_TOOL::Reset(), COMMON_TOOLS::ResetLocalCoords(), GERBVIEW_SELECTION_TOOL::selectCursor(), SELECTION_TOOL::selectCursor(), PL_SELECTION_TOOL::selectMultiple(), EE_SELECTION_TOOL::selectMultiple(), SELECTION_TOOL::selectMultiple(), EE_SELECTION_TOOL::SelectNode(), ZOOM_TOOL::selectRegion(), ALIGN_DISTRIBUTE_TOOL::selectTarget(), PICKER_TOOL::setControls(), PCBNEW_PICKER_TOOL::setControls(), EE_POINT_EDITOR::setEditedPoint(), PL_POINT_EDITOR::setEditedPoint(), POINT_EDITOR::setEditedPoint(), SCH_DRAWING_TOOLS::SingleClickPlace(), LIB_DRAWING_TOOLS::TwoClickPlace(), SCH_DRAWING_TOOLS::TwoClickPlace(), EE_POINT_EDITOR::updateEditedPoint(), PL_POINT_EDITOR::updateEditedPoint(), POINT_EDITOR::updateEditedPoint(), LIB_MOVE_TOOL::updateModificationPoint(), PL_EDIT_TOOL::updateModificationPoint(), EDIT_TOOL::updateModificationPoint(), and COMMON_TOOLS::ZoomCenter().

◆ Go()

template<class T >
void TOOL_INTERACTIVE::Go ( int(T::*)(const TOOL_EVENT &)  aStateFunc,
const TOOL_EVENT_LIST aConditions = TOOL_EVENTTC_ANYTA_ANY ) 
)
inherited

Function Go()

Defines which state (aStateFunc) to go when a certain event arrives (aConditions). No conditions means any event.

Definition at line 129 of file tool_interactive.h.

131 {
132  TOOL_STATE_FUNC sptr = std::bind( aStateFunc, static_cast<T*>( this ), std::placeholders::_1 );
133 
134  goInternal( sptr, aConditions );
135 }
std::function< int(const TOOL_EVENT &)> TOOL_STATE_FUNC
Definition: tool_base.h:58
void goInternal(TOOL_STATE_FUNC &aState, const TOOL_EVENT_LIST &aConditions)

References TOOL_INTERACTIVE::goInternal().

Referenced by LENGTH_TUNER_TOOL::setTransitions(), ZOOM_TOOL::setTransitions(), AUTOPLACE_TOOL::setTransitions(), MICROWAVE_TOOL::setTransitions(), ROUTER_TOOL::setTransitions(), CVPCB_FOOTPRINT_VIEWER_CONTROL::setTransitions(), LIB_PIN_TOOL::setTransitions(), PAD_TOOL::setTransitions(), EE_INSPECTION_TOOL::setTransitions(), PL_DRAWING_TOOLS::setTransitions(), KICAD_MANAGER_CONTROL::setTransitions(), COMMON_CONTROL::setTransitions(), LIB_DRAWING_TOOLS::setTransitions(), ZONE_FILLER_TOOL::setTransitions(), EE_POINT_EDITOR::setTransitions(), PL_POINT_EDITOR::setTransitions(), SCH_MOVE_TOOL::setTransitions(), LIB_MOVE_TOOL::setTransitions(), GERBVIEW_CONTROL::setTransitions(), SCH_DRAWING_TOOLS::setTransitions(), GLOBAL_EDIT_TOOL::setTransitions(), POINT_EDITOR::setTransitions(), CVPCB_FOOTPRINT_VIEWER_SELECTION_TOOL::setTransitions(), LIB_CONTROL::setTransitions(), PL_EDITOR_CONTROL::setTransitions(), LIB_EDIT_TOOL::setTransitions(), SCH_EDIT_TOOL::setTransitions(), PL_EDIT_TOOL::setTransitions(), POSITION_RELATIVE_TOOL::setTransitions(), GERBVIEW_SELECTION_TOOL::setTransitions(), COMMON_TOOLS::setTransitions(), SCH_LINE_WIRE_BUS_TOOL::setTransitions(), PCB_INSPECTION_TOOL::setTransitions(), PCBNEW_CONTROL::setTransitions(), ALIGN_DISTRIBUTE_TOOL::setTransitions(), MODULE_EDITOR_TOOLS::setTransitions(), CVPCB_CONTROL::setTransitions(), CVPCB_ASSOCIATION_TOOL::setTransitions(), PCBNEW_PICKER_TOOL::setTransitions(), PICKER_TOOL::setTransitions(), PCB_EDITOR_CONTROL::setTransitions(), DRAWING_TOOL::setTransitions(), EDIT_TOOL::setTransitions(), SELECTION_TOOL::setTransitions(), SCH_EDITOR_CONTROL::setTransitions(), PL_SELECTION_TOOL::setTransitions(), EE_SELECTION_TOOL::setTransitions(), and setTransitions().

◆ Init()

bool PCB_TOOL_BASE::Init ( )
overridevirtualinherited

Function Init() Init() is called once upon a registration of the tool.

Returns
True if the initialization went fine, false - otherwise.

Reimplemented from TOOL_BASE.

Reimplemented in EDIT_TOOL, SELECTION_TOOL, DRAWING_TOOL, POSITION_RELATIVE_TOOL, PCB_EDITOR_CONTROL, POINT_EDITOR, MODULE_EDITOR_TOOLS, GLOBAL_EDIT_TOOL, PAD_TOOL, PCB_INSPECTION_TOOL, and ROUTER_TOOL.

Definition at line 219 of file pcb_tool_base.cpp.

220 {
221  // A basic context manu. Many (but not all) tools will choose to override this.
222 
223  auto& ctxMenu = m_menu.GetMenu();
224 
225  // cancel current tool goes in main context menu at the top if present
227  ctxMenu.AddSeparator( 1 );
228 
229  // Finally, add the standard zoom/grid items
230  getEditFrame<PCB_BASE_FRAME>()->AddStandardSubMenus( m_menu );
231 
232  return true;
233 }
static bool ShowAlways(const SELECTION &aSelection)
Function ShowAlways The default condition function (always returns true).
TOOL_MENU m_menu
functions below are not yet implemented - their interface may change
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:46
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Function AddItem()

References CONDITIONAL_MENU::AddItem(), ACTIONS::cancelInteractive, TOOL_MENU::GetMenu(), TOOL_INTERACTIVE::m_menu, and SELECTION_CONDITIONS::ShowAlways().

◆ IsToolActive()

bool TOOL_BASE::IsToolActive ( ) const
inherited

Definition at line 31 of file tool_base.cpp.

32 {
33  return m_toolMgr->IsToolActive( m_toolId );
34 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
TOOL_ID m_toolId
Unique identifier for the tool, assigned by a TOOL_MANAGER instance.
Definition: tool_base.h:214
bool IsToolActive(TOOL_ID aId) const
Function IsToolActive() Returns true if a tool with given id is active (executing)

References TOOL_MANAGER::IsToolActive(), TOOL_BASE::m_toolId, and TOOL_BASE::m_toolMgr.

◆ module()

◆ Reset()

void DRC::Reset ( RESET_REASON  aReason)
overridevirtual

Function Reset() Brings the tool to a known, initial state.

If the tool claimed anything from the model or the view, it must release it when its reset.

Parameters
aReasoncontains information about the reason of tool reset.

Reimplemented from PCB_TOOL_BASE.

Definition at line 104 of file drc.cpp.

105 {
106  m_pcbEditorFrame = getEditFrame<PCB_EDIT_FRAME>();
107 
108  if( aReason == MODEL_RELOAD )
109  {
110  if( m_drcDialog )
111  DestroyDRCDialog( wxID_OK );
112 
114 
116  }
117 }
void DestroyDRCDialog(int aReason)
Deletes this ui dialog box and zeros out its pointer to remember the state of the dialog's existence.
Definition: drc.cpp:172
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc.h:239
Model changes (required full reload)
Definition: tool_base.h:82
BOARD * m_pcb
Definition: drc.h:237
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:236
EDA_UNITS_T GetUserUnits() const
Return the user units currently in use.
BOARD * GetBoard() const
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
void SetUnitsProvider(UNITS_PROVIDER aUnitsProvider)
Set the provider for the units (this will be called for each new marker constructed)

References DestroyDRCDialog(), PCB_BASE_FRAME::GetBoard(), EDA_BASE_FRAME::GetUserUnits(), m_drcDialog, m_markerFactory, m_pcb, m_pcbEditorFrame, TOOL_BASE::MODEL_RELOAD, and DRC_MARKER_FACTORY::SetUnitsProvider().

◆ RunMainStack()

void TOOL_INTERACTIVE::RunMainStack ( std::function< void()>  aFunc)
inherited

Function RunMainStack()

Calls a function using the main stack.

Parameters
aFuncis the function to be calls.

Definition at line 87 of file tool_interactive.cpp.

88 {
89  m_toolMgr->RunMainStack( this, std::move( aFunc ) );
90 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
void RunMainStack(TOOL_BASE *aTool, std::function< void()> aFunc)

References TOOL_BASE::m_toolMgr, and TOOL_MANAGER::RunMainStack().

Referenced by DRAWING_TOOL::PlaceText().

◆ RunTests()

void DRC::RunTests ( wxTextCtrl *  aMessages = NULL)

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 340 of file drc.cpp.

341 {
342  // be sure m_pcb is the current board, not a old one
343  // ( the board can be reloaded )
345 
346  if( aMessages )
347  {
348  aMessages->AppendText( _( "Board Outline...\n" ) );
349  wxSafeYield();
350  }
351 
352  testOutline();
353 
354  // someone should have cleared the two lists before calling this.
355  if( !testNetClasses() )
356  {
357  // testing the netclasses is a special case because if the netclasses
358  // do not pass the BOARD_DESIGN_SETTINGS checks, then every member of a net
359  // class (a NET) will cause its items such as tracks, vias, and pads
360  // to also fail. So quit after *all* netclass errors have been reported.
361  if( aMessages )
362  aMessages->AppendText( _( "Aborting\n" ) );
363 
364  // update the m_drcDialog listboxes
365  updatePointers();
366 
367  return;
368  }
369 
370  // test pad to pad clearances, nothing to do with tracks, vias or zones.
371  if( m_doPad2PadTest )
372  {
373  if( aMessages )
374  {
375  aMessages->AppendText( _( "Pad clearances...\n" ) );
376  wxSafeYield();
377  }
378 
379  testPad2Pad();
380  }
381 
382  // test clearances between drilled holes
383  if( aMessages )
384  {
385  aMessages->AppendText( _( "Drill clearances...\n" ) );
386  wxSafeYield();
387  }
388 
390 
391  // caller (a wxTopLevelFrame) is the wxDialog or the Pcb Editor frame that call DRC:
392  wxWindow* caller = aMessages ? aMessages->GetParent() : m_pcbEditorFrame;
393 
394  if( m_refillZones )
395  {
396  if( aMessages )
397  aMessages->AppendText( _( "Refilling all zones...\n" ) );
398 
399  m_toolMgr->GetTool<ZONE_FILLER_TOOL>()->FillAllZones( caller );
400  }
401  else
402  {
403  if( aMessages )
404  aMessages->AppendText( _( "Checking zone fills...\n" ) );
405 
406  m_toolMgr->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( caller );
407  }
408 
409  // test track and via clearances to other tracks, pads, and vias
410  if( aMessages )
411  {
412  aMessages->AppendText( _( "Track clearances...\n" ) );
413  wxSafeYield();
414  }
415 
416  testTracks( aMessages ? aMessages->GetParent() : m_pcbEditorFrame, true );
417 
418  // test zone clearances to other zones
419  if( aMessages )
420  {
421  aMessages->AppendText( _( "Zone to zone clearances...\n" ) );
422  wxSafeYield();
423  }
424 
425  testZones();
426 
427  // find and gather unconnected pads.
428  if( m_doUnconnectedTest )
429  {
430  if( aMessages )
431  {
432  aMessages->AppendText( _( "Unconnected pads...\n" ) );
433  aMessages->Refresh();
434  }
435 
436  testUnconnected();
437  }
438 
439  // find and gather vias, tracks, pads inside keepout areas.
440  if( m_doKeepoutTest )
441  {
442  if( aMessages )
443  {
444  aMessages->AppendText( _( "Keepout areas ...\n" ) );
445  aMessages->Refresh();
446  }
447 
449  }
450 
451  // find and gather vias, tracks, pads inside text boxes.
452  if( aMessages )
453  {
454  aMessages->AppendText( _( "Text and graphic clearances...\n" ) );
455  wxSafeYield();
456  }
457 
459 
460  // find overlapping courtyard ares.
463  {
464  if( aMessages )
465  {
466  aMessages->AppendText( _( "Courtyard areas...\n" ) );
467  aMessages->Refresh();
468  }
469 
471  }
472 
473  for( DRC_ITEM* footprintItem : m_footprints )
474  delete footprintItem;
475 
476  m_footprints.clear();
477  m_footprintsTested = false;
478 
479  if( m_testFootprints && !Kiface().IsSingle() )
480  {
481  if( aMessages )
482  {
483  aMessages->AppendText( _( "Checking footprints against schematic...\n" ) );
484  aMessages->Refresh();
485  }
486 
487  NETLIST netlist;
489 
490  if( m_drcDialog )
491  m_drcDialog->Raise();
492 
494  m_footprintsTested = true;
495  }
496 
497  // Check if there are items on disabled layers
499 
500  if( aMessages )
501  {
502  aMessages->AppendText( _( "Items on disabled layers...\n" ) );
503  aMessages->Refresh();
504  }
505 
506  m_drcRun = true;
507 
508  // update the m_drcDialog listboxes
509  updatePointers();
510 
511  if( aMessages )
512  {
513  // no newline on this one because it is last, don't want the window
514  // to unnecessarily scroll.
515  aMessages->AppendText( _( "Finished" ) );
516  }
517 }
bool m_refillZones
Definition: drc.h:205
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc.h:239
Class DRC_ITEM is a holder for a DRC (in Pcbnew) or ERC (in Eeschema) error item.
Definition: drc_item.h:48
void testCopperTextAndGraphics()
Definition: drc.cpp:930
DRC_LIST m_footprints
list of footprint warnings, as DRC_ITEMs
Definition: drc.h:243
bool m_ProhibitOverlappingCourtyards
check for overlapping courtyards in DRC
void testKeepoutAreas()
Definition: drc.cpp:883
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:540
void testOutline()
Test that the board outline is contiguous and composed of valid elements.
Definition: drc.cpp:1159
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:51
BOARD * m_pcb
Definition: drc.h:237
static void TestFootprints(NETLIST &aNetlist, BOARD *aPCB, EDA_UNITS_T aUnits, DRC_LIST &aDRCList)
Test the board footprints against a netlist.
Definition: drc.cpp:1351
void testDrilledHoles()
Definition: drc.cpp:686
bool m_testFootprints
Definition: drc.h:207
bool m_doKeepoutTest
Definition: drc.h:203
Class ZONE_FILLER_TOOL.
Class NETLIST stores all of information read from a netlist along with the flags used to update the N...
Definition: pcb_netlist.h:214
void testZones()
Definition: drc.cpp:847
void updatePointers()
Update needed pointers from the one pointer which is known not to change.
Definition: drc.cpp:520
bool m_drcRun
Definition: drc.h:244
void testDisabledLayers()
Tests for items placed on disabled layers (causing false connections).
Definition: drc.cpp:1173
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:236
#define _(s)
bool m_doPad2PadTest
Definition: drc.h:200
void testPad2Pad()
Definition: drc.cpp:647
bool m_footprintsTested
Definition: drc.h:245
bool m_RequireCourtyards
require courtyard definitions in footprints
bool testNetClasses()
Go through each NETCLASS and verifies that its clearance, via size, track width, and track clearance ...
Definition: drc.cpp:624
void testTracks(wxWindow *aActiveWindow, bool aShowProgressBar)
Perform the DRC on all tracks.
Definition: drc.cpp:759
EDA_UNITS_T GetUserUnits() const
Definition: dialog_shim.h:135
BOARD * GetBoard() const
void testUnconnected()
Definition: drc.cpp:816
bool FetchNetlistFromSchematic(NETLIST &aNetlist, FETCH_NETLIST_MODE aMode)
bool m_doUnconnectedTest
Definition: drc.h:201
void doFootprintOverlappingDrc()
Test for footprint courtyard overlaps.
Definition: drc.cpp:1342

References _, PCB_EDIT_FRAME::ANNOTATION_DIALOG, doFootprintOverlappingDrc(), PCB_EDIT_FRAME::FetchNetlistFromSchematic(), PCB_BASE_FRAME::GetBoard(), BOARD::GetDesignSettings(), TOOL_MANAGER::GetTool(), DIALOG_SHIM::GetUserUnits(), Kiface(), m_doKeepoutTest, m_doPad2PadTest, m_doUnconnectedTest, m_drcDialog, m_drcRun, m_footprints, m_footprintsTested, m_pcb, m_pcbEditorFrame, BOARD_DESIGN_SETTINGS::m_ProhibitOverlappingCourtyards, m_refillZones, BOARD_DESIGN_SETTINGS::m_RequireCourtyards, m_testFootprints, TOOL_BASE::m_toolMgr, testCopperTextAndGraphics(), testDisabledLayers(), testDrilledHoles(), TestFootprints(), testKeepoutAreas(), testNetClasses(), testOutline(), testPad2Pad(), testTracks(), testUnconnected(), testZones(), and updatePointers().

Referenced by DIALOG_DRC_CONTROL::OnStartdrcClick().

◆ selection() [1/2]

const PCBNEW_SELECTION & PCB_TOOL_BASE::selection ( ) const
protectedinherited

Definition at line 257 of file pcb_tool_base.cpp.

258 {
259  auto selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
260  const auto& selection = selTool->GetSelection();
261  return selection;
262 }
Class SELECTION_TOOL.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
const PCBNEW_SELECTION & selection() const

References TOOL_MANAGER::GetTool(), and TOOL_BASE::m_toolMgr.

Referenced by AUTOPLACE_TOOL::autoplaceSelected(), PCB_INSPECTION_TOOL::calculateSelectionRatsnest(), ROUTER_TOOL::CanInlineDrag(), EDIT_TOOL::changeTrackWidthOnClick(), PAD_TOOL::copyPadSettings(), EDIT_TOOL::copyToClipboard(), EDIT_TOOL::CreateArray(), MODULE_EDITOR_TOOLS::CreatePadFromShapes(), PCB_INSPECTION_TOOL::CrossProbePcbToSch(), PCB_TOOL_BASE::doInteractiveItemPlacement(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::drawSegment(), DRAWING_TOOL::DrawZone(), EDIT_TOOL::Duplicate(), EDIT_TOOL::EditFpInFpEditor(), PAD_TOOL::EnumeratePads(), GLOBAL_EDIT_TOOL::ExchangeFootprints(), SELECTION_TOOL::expandConnection(), MODULE_EDITOR_TOOLS::ExplodePadToShapes(), SELECTION_TOOL::filterSelection(), EDIT_TOOL::Flip(), DRAWING_TOOL::getSourceZoneForAction(), PCB_INSPECTION_TOOL::highlightNet(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), PCB_INSPECTION_TOOL::LocalRatsnestTool(), EDIT_TOOL::Mirror(), PCB_EDITOR_CONTROL::modifyLockSelected(), EDIT_TOOL::Move(), EDIT_TOOL::MoveExact(), POINT_EDITOR::OnSelectionChange(), PAD_TOOL::pastePadProperties(), PCBNEW_CONTROL::placeBoardItems(), DRAWING_TOOL::PlaceImportedGraphics(), PCB_EDITOR_CONTROL::PlaceModule(), PCB_EDITOR_CONTROL::PlaceTarget(), DRAWING_TOOL::PlaceText(), POSITION_RELATIVE_TOOL::PositionRelative(), EDIT_TOOL::Properties(), PAD_TOOL::pushPadSettings(), EDIT_TOOL::Rotate(), SELECTION_TOOL::selectCopper(), PCB_TOOL_BASE::selection(), SELECTION_TOOL::selectNet(), DRAWING_TOOL::SetAnchor(), PCB_EDITOR_CONTROL::TrackWidthDec(), PCB_EDITOR_CONTROL::TrackWidthInc(), PCBNEW_CONTROL::UpdateMessagePanel(), PCB_INSPECTION_TOOL::UpdateSelectionRatsnest(), PCB_EDITOR_CONTROL::ViaSizeDec(), PCB_EDITOR_CONTROL::ViaSizeInc(), PCB_EDITOR_CONTROL::ZoneDuplicate(), ZONE_FILLER_TOOL::ZoneFill(), PCB_EDITOR_CONTROL::ZoneMerge(), and ZONE_FILLER_TOOL::ZoneUnfill().

◆ selection() [2/2]

PCBNEW_SELECTION & PCB_TOOL_BASE::selection ( )
protectedinherited

Definition at line 265 of file pcb_tool_base.cpp.

266 {
267  auto selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
268  auto& selection = selTool->GetSelection();
269  return selection;
270 }
Class SELECTION_TOOL.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
const PCBNEW_SELECTION & selection() const

References TOOL_MANAGER::GetTool(), TOOL_BASE::m_toolMgr, and PCB_TOOL_BASE::selection().

◆ SetContextMenu()

void TOOL_INTERACTIVE::SetContextMenu ( ACTION_MENU aMenu,
CONTEXT_MENU_TRIGGER  aTrigger = CMENU_BUTTON 
)
inherited

Function SetContextMenu()

Assigns a context menu and tells when it should be activated.

Parameters
aMenuis the menu to be assigned.
aTriggerdetermines conditions upon which the context menu is activated.

Definition at line 76 of file tool_interactive.cpp.

77 {
78  if( aMenu )
79  aMenu->SetTool( this );
80  else
81  aTrigger = CMENU_OFF;
82 
83  m_toolMgr->ScheduleContextMenu( this, aMenu, aTrigger );
84 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
void SetTool(TOOL_INTERACTIVE *aTool)
Function SetTool() Sets a tool that is the creator of the menu.
void ScheduleContextMenu(TOOL_BASE *aTool, ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger)
Sets behaviour of the tool's context popup menu.

References CMENU_OFF, TOOL_BASE::m_toolMgr, TOOL_MANAGER::ScheduleContextMenu(), and ACTION_MENU::SetTool().

Referenced by GERBVIEW_SELECTION_TOOL::disambiguationMenu(), PL_SELECTION_TOOL::doSelectionMenu(), EE_SELECTION_TOOL::doSelectionMenu(), SELECTION_TOOL::doSelectionMenu(), ROUTER_TOOL::MainLoop(), LENGTH_TUNER_TOOL::MainLoop(), TOOL_MENU::ShowContextMenu(), and SCH_LINE_WIRE_BUS_TOOL::UnfoldBus().

◆ SetEditModules()

void PCB_TOOL_BASE::SetEditModules ( bool  aEnabled)
inlineinherited

Function SetEditModules()

Toggles edit module mode. When enabled, one may select parts of modules individually (graphics, pads, etc.), so they can be modified.

Parameters
aEnableddecides if the mode should be enabled.

Definition at line 97 of file pcb_tool_base.h.

98  {
99  m_editModules = aEnabled;
100  }

References PCB_TOOL_BASE::m_editModules.

◆ setTransitions()

void DRC::setTransitions ( )
overrideprivatevirtual

Sets up handlers for various events.

Reimplemented from PCB_TOOL_BASE.

Definition at line 1403 of file drc.cpp.

1404 {
1405  Go( &DRC::ShowDRCDialog, PCB_ACTIONS::runDRC.MakeEvent() );
1406 }
void ShowDRCDialog(wxWindow *aParent)
Open a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and create...
Definition: drc.cpp:120
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
static TOOL_ACTION runDRC
Definition: pcb_actions.h:324

References TOOL_INTERACTIVE::Go(), PCB_ACTIONS::runDRC, and ShowDRCDialog().

◆ ShowDRCDialog() [1/2]

void DRC::ShowDRCDialog ( wxWindow *  aParent)

Open 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 another 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 another dialog, not from the PCB editor frame

Definition at line 120 of file drc.cpp.

121 {
122  bool show_dlg_modal = true;
123 
124  // the dialog needs a parent frame. if it is not specified, this is
125  // the PCB editor frame specified in DRC class.
126  if( !aParent )
127  {
128  // if any parent is specified, the dialog is modal.
129  // if this is the default PCB editor frame, it is not modal
130  show_dlg_modal = false;
131  aParent = m_pcbEditorFrame;
132  }
133 
134  Activate();
136 
137  if( !m_drcDialog )
138  {
139  m_drcDialog = new DIALOG_DRC_CONTROL( this, m_pcbEditorFrame, aParent );
140  updatePointers();
141 
143 
144  if( show_dlg_modal )
145  m_drcDialog->ShowModal();
146  else
147  m_drcDialog->Show( true );
148  }
149  else // The dialog is just not visible (because the user has double clicked on an error item)
150  {
151  updatePointers();
152  m_drcDialog->Show( true );
153  }
154 }
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:73
bool m_doCreateRptFile
Definition: drc.h:204
DIALOG_DRC_CONTROL * m_drcDialog
Definition: drc.h:239
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:109
void updatePointers()
Update needed pointers from the one pointer which is known not to change.
Definition: drc.cpp:520
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:236
bool Show(bool show) override
friend class DIALOG_DRC_CONTROL
Definition: drc.h:188
wxString m_rptFilename
Definition: drc.h:209
void Activate()
Function Activate() Runs the tool.
void SetRptSettings(bool aEnable, const wxString &aFileName)
Enable/disable the report file creation.
Definition: dialog_drc.cpp:195

References TOOL_INTERACTIVE::Activate(), DIALOG_DRC_CONTROL, m_doCreateRptFile, m_drcDialog, m_pcbEditorFrame, m_rptFilename, TOOL_BASE::m_toolMgr, TOOL_MANAGER::RunAction(), PCB_ACTIONS::selectionClear, DIALOG_DRC_CONTROL::SetRptSettings(), DIALOG_SHIM::Show(), and updatePointers().

Referenced by DIALOG_PLOT::onRunDRC(), setTransitions(), and ShowDRCDialog().

◆ ShowDRCDialog() [2/2]

int DRC::ShowDRCDialog ( const TOOL_EVENT aEvent)

Definition at line 157 of file drc.cpp.

158 {
159  ShowDRCDialog( nullptr );
160  return 0;
161 }
void ShowDRCDialog(wxWindow *aParent)
Open a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and create...
Definition: drc.cpp:120

References ShowDRCDialog().

◆ testCopperDrawItem()

void DRC::testCopperDrawItem ( DRAWSEGMENT aDrawing)
private

Definition at line 973 of file drc.cpp.

974 {
975  std::vector<SEG> itemShape;
976  int itemWidth = aItem->GetWidth();
977 
978  switch( aItem->GetShape() )
979  {
980  case S_ARC:
981  {
982  SHAPE_ARC arc( aItem->GetCenter(), aItem->GetArcStart(), (double) aItem->GetAngle() / 10.0 );
983 
984  auto l = arc.ConvertToPolyline();
985 
986  for( int i = 0; i < l.SegmentCount(); i++ )
987  itemShape.push_back( l.CSegment(i) );
988 
989  break;
990  }
991 
992  case S_SEGMENT:
993  itemShape.emplace_back( SEG( aItem->GetStart(), aItem->GetEnd() ) );
994  break;
995 
996  case S_CIRCLE:
997  {
998  // SHAPE_CIRCLE has no ConvertToPolyline() method, so use a 360.0 SHAPE_ARC
999  SHAPE_ARC circle( aItem->GetCenter(), aItem->GetEnd(), 360.0 );
1000 
1001  auto l = circle.ConvertToPolyline();
1002 
1003  for( int i = 0; i < l.SegmentCount(); i++ )
1004  itemShape.push_back( l.CSegment(i) );
1005 
1006  break;
1007  }
1008 
1009  case S_CURVE:
1010  {
1011  aItem->RebuildBezierToSegmentsPointsList( aItem->GetWidth() );
1012  wxPoint start_pt = aItem->GetBezierPoints()[0];
1013 
1014  for( unsigned int jj = 1; jj < aItem->GetBezierPoints().size(); jj++ )
1015  {
1016  wxPoint end_pt = aItem->GetBezierPoints()[jj];
1017  itemShape.emplace_back( SEG( start_pt, end_pt ) );
1018  start_pt = end_pt;
1019  }
1020 
1021  break;
1022  }
1023 
1024  default:
1025  break;
1026  }
1027 
1028  // Test tracks and vias
1029  for( auto track : m_pcb->Tracks() )
1030  {
1031  if( !track->IsOnLayer( aItem->GetLayer() ) )
1032  continue;
1033 
1034  int minDist = ( track->GetWidth() + itemWidth ) / 2 + track->GetClearance( NULL );
1035  SEG trackAsSeg( track->GetStart(), track->GetEnd() );
1036 
1037  for( const auto& itemSeg : itemShape )
1038  {
1039  if( trackAsSeg.Distance( itemSeg ) < minDist )
1040  {
1041  if( track->Type() == PCB_VIA_T )
1043  track, aItem, itemSeg, DRCE_VIA_NEAR_COPPER ) );
1044  else
1046  track, aItem, itemSeg, DRCE_TRACK_NEAR_COPPER ) );
1047  break;
1048  }
1049  }
1050  }
1051 
1052  // Test pads
1053  for( auto pad : m_pcb->GetPads() )
1054  {
1055  if( !pad->IsOnLayer( aItem->GetLayer() ) )
1056  continue;
1057 
1058  // Graphic items are allowed to act as net-ties within their own footprint
1059  if( pad->GetParent() == aItem->GetParent() )
1060  continue;
1061 
1062  SHAPE_POLY_SET padOutline;
1063  pad->TransformShapeWithClearanceToPolygon( padOutline, pad->GetClearance( NULL ) );
1064 
1065  for( const auto& itemSeg : itemShape )
1066  {
1067  if( padOutline.Distance( itemSeg, itemWidth ) == 0 )
1068  {
1070  break;
1071  }
1072  }
1073  }
1074 }
usual segment : line with rounded ends
#define DRCE_VIA_NEAR_COPPER
via and copper graphic collide or are too close
Definition: drc.h:87
BOARD * m_pcb
Definition: drc.h:237
#define DRCE_TRACK_NEAR_COPPER
track & copper graphic collide or are too close
Definition: drc.h:86
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
Class SHAPE_POLY_SET.
Arcs (with rounded ends)
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
Bezier Curve.
Definition: seg.h:36
const std::vector< D_PAD * > GetPads()
Function GetPads returns a reference to a list of all the pads.
int Distance(VECTOR2I aPoint)
Function DistanceToPolygon computes the minimum distance between aPoint and all the polygons in the s...
size_t i
Definition: json11.cpp:597
#define DRCE_PAD_NEAR_COPPER
pad and copper graphic collide or are too close
Definition: drc.h:88
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=500.0) const
Constructs a SHAPE_LINE_CHAIN of segments from a given arc.
Definition: shape_arc.cpp:240
TRACKS & Tracks()
Definition: class_board.h:227

References addMarkerToPcb(), SHAPE_ARC::ConvertToPolyline(), SHAPE_POLY_SET::Distance(), DRCE_PAD_NEAR_COPPER, DRCE_TRACK_NEAR_COPPER, DRCE_VIA_NEAR_COPPER, DRAWSEGMENT::GetAngle(), DRAWSEGMENT::GetArcStart(), DRAWSEGMENT::GetBezierPoints(), DRAWSEGMENT::GetCenter(), DRAWSEGMENT::GetEnd(), BOARD_ITEM::GetLayer(), BOARD::GetPads(), BOARD_ITEM::GetParent(), DRAWSEGMENT::GetShape(), DRAWSEGMENT::GetStart(), DRAWSEGMENT::GetWidth(), i, m_markerFactory, m_pcb, DRC_MARKER_FACTORY::NewMarker(), PCB_VIA_T, DRAWSEGMENT::RebuildBezierToSegmentsPointsList(), S_ARC, S_CIRCLE, S_CURVE, S_SEGMENT, and BOARD::Tracks().

Referenced by testCopperTextAndGraphics().

◆ testCopperTextAndGraphics()

void DRC::testCopperTextAndGraphics ( )
private

Definition at line 930 of file drc.cpp.

931 {
932  // Test copper items for clearance violations with vias, tracks and pads
933 
934  for( BOARD_ITEM* brdItem : m_pcb->Drawings() )
935  {
936  if( IsCopperLayer( brdItem->GetLayer() ) )
937  {
938  if( brdItem->Type() == PCB_TEXT_T )
939  testCopperTextItem( brdItem );
940  else if( brdItem->Type() == PCB_LINE_T )
941  testCopperDrawItem( static_cast<DRAWSEGMENT*>( brdItem ));
942  }
943  }
944 
945  for( MODULE* module : m_pcb->Modules() )
946  {
947  TEXTE_MODULE& ref = module->Reference();
948  TEXTE_MODULE& val = module->Value();
949 
950  if( ref.IsVisible() && IsCopperLayer( ref.GetLayer() ) )
951  testCopperTextItem( &ref );
952 
953  if( val.IsVisible() && IsCopperLayer( val.GetLayer() ) )
954  testCopperTextItem( &val );
955 
956  if( module->IsNetTie() )
957  continue;
958 
959  for( auto item : module->GraphicalItems() )
960  {
961  if( IsCopperLayer( item->GetLayer() ) )
962  {
963  if( item->Type() == PCB_MODULE_TEXT_T && ( (TEXTE_MODULE*) item )->IsVisible() )
964  testCopperTextItem( item );
965  else if( item->Type() == PCB_MODULE_EDGE_T )
966  testCopperDrawItem( static_cast<DRAWSEGMENT*>( item ));
967  }
968  }
969  }
970 }
TEXTE_MODULE & Reference()
Definition: class_module.h:457
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
bool IsVisible() const
Definition: eda_text.h:170
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
void testCopperDrawItem(DRAWSEGMENT *aDrawing)
Definition: drc.cpp:973
DRAWINGS & GraphicalItems()
Definition: class_module.h:175
void testCopperTextItem(BOARD_ITEM *aTextItem)
Definition: drc.cpp:1077
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
BOARD * m_pcb
Definition: drc.h:237
bool IsNetTie() const
Definition: class_module.h:247
MODULES & Modules()
Definition: class_board.h:236
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:456
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
MODULE * module() const
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
DRAWINGS & Drawings()
Definition: class_board.h:245

References BOARD::Drawings(), BOARD_ITEM::GetLayer(), MODULE::GraphicalItems(), IsCopperLayer(), MODULE::IsNetTie(), EDA_TEXT::IsVisible(), m_pcb, PCB_TOOL_BASE::module(), BOARD::Modules(), PCB_LINE_T, PCB_MODULE_EDGE_T, PCB_MODULE_TEXT_T, PCB_TEXT_T, MODULE::Reference(), testCopperDrawItem(), testCopperTextItem(), and MODULE::Value().

Referenced by RunTests().

◆ testCopperTextItem()

void DRC::testCopperTextItem ( BOARD_ITEM aTextItem)
private

Definition at line 1077 of file drc.cpp.

1078 {
1079  EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( aTextItem );
1080 
1081  if( text == nullptr )
1082  return;
1083 
1084  std::vector<wxPoint> textShape; // a buffer to store the text shape (set of segments)
1085  int textWidth = text->GetThickness();
1086 
1087  // So far the bounding box makes up the text-area
1088  text->TransformTextShapeToSegmentList( textShape );
1089 
1090  if( textShape.size() == 0 ) // Should not happen (empty text?)
1091  return;
1092 
1093  EDA_RECT bbox = text->GetTextBox();
1094  SHAPE_RECT rect_area( bbox.GetX(), bbox.GetY(), bbox.GetWidth(), bbox.GetHeight() );
1095 
1096  // Test tracks and vias
1097  for( auto track : m_pcb->Tracks() )
1098  {
1099  if( !track->IsOnLayer( aTextItem->GetLayer() ) )
1100  continue;
1101 
1102  int minDist = ( track->GetWidth() + textWidth ) / 2 + track->GetClearance( NULL );
1103  SEG trackAsSeg( track->GetStart(), track->GetEnd() );
1104 
1105  // Fast test to detect a trach segment candidate inside the text bounding box
1106  if( !rect_area.Collide( trackAsSeg, minDist ) )
1107  continue;
1108 
1109  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
1110  {
1111  SEG textSeg( textShape[jj], textShape[jj+1] );
1112 
1113  if( trackAsSeg.Distance( textSeg ) < minDist )
1114  {
1115  if( track->Type() == PCB_VIA_T )
1117  track, aTextItem, textSeg, DRCE_VIA_NEAR_COPPER ) );
1118  else
1120  track, aTextItem, textSeg, DRCE_TRACK_NEAR_COPPER ) );
1121  break;
1122  }
1123  }
1124  }
1125 
1126  // Test pads
1127  for( auto pad : m_pcb->GetPads() )
1128  {
1129  if( !pad->IsOnLayer( aTextItem->GetLayer() ) )
1130  continue;
1131 
1132  // Fast test to detect a pad candidate inside the text bounding box
1133  // Finer test (time consumming) is made only for pads near the text.
1134  int bb_radius = pad->GetBoundingRadius() + pad->GetClearance( NULL );
1135  VECTOR2I shape_pos( pad->ShapePos() );
1136 
1137  if( !rect_area.Collide( SEG( shape_pos, shape_pos ), bb_radius ) )
1138  continue;
1139 
1140  SHAPE_POLY_SET padOutline;
1141 
1142  int minDist = textWidth/2 + pad->GetClearance( NULL );
1143  pad->TransformShapeWithClearanceToPolygon( padOutline, 0 );
1144 
1145  for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
1146  {
1147  SEG textSeg( textShape[jj], textShape[jj+1] );
1148 
1149  if( padOutline.Distance( textSeg, 0 ) <= minDist )
1150  {
1152  break;
1153  }
1154  }
1155  }
1156 }
int GetX() const
Definition: eda_rect.h:111
int GetWidth() const
Definition: eda_rect.h:119
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:148
#define DRCE_VIA_NEAR_COPPER
via and copper graphic collide or are too close
Definition: drc.h:87
BOARD * m_pcb
Definition: drc.h:237
Class EDA_TEXT is a mix-in class (via multiple inheritance) that handles texts such as labels,...
Definition: eda_text.h:109
#define DRCE_TRACK_NEAR_COPPER
track & copper graphic collide or are too close
Definition: drc.h:86
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
EDA_RECT GetTextBox(int aLine=-1, int aThickness=-1, bool aInvertY=false) const
Function GetTextBox useful in multiline texts to calculate the full text or a line area (for zones fi...
Definition: eda_text.cpp:199
Class SHAPE_POLY_SET.
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
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:559
int GetHeight() const
Definition: eda_rect.h:120
Definition: seg.h:36
const std::vector< D_PAD * > GetPads()
Function GetPads returns a reference to a list of all the pads.
int Distance(VECTOR2I aPoint)
Function DistanceToPolygon computes the minimum distance between aPoint and all the polygons in the s...
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
int GetY() const
Definition: eda_rect.h:112
#define DRCE_PAD_NEAR_COPPER
pad and copper graphic collide or are too close
Definition: drc.h:88
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
TRACKS & Tracks()
Definition: class_board.h:227

References addMarkerToPcb(), SHAPE_POLY_SET::Distance(), DRCE_PAD_NEAR_COPPER, DRCE_TRACK_NEAR_COPPER, DRCE_VIA_NEAR_COPPER, EDA_RECT::GetHeight(), BOARD_ITEM::GetLayer(), BOARD::GetPads(), EDA_TEXT::GetTextBox(), EDA_TEXT::GetThickness(), EDA_RECT::GetWidth(), EDA_RECT::GetX(), EDA_RECT::GetY(), m_markerFactory, m_pcb, DRC_MARKER_FACTORY::NewMarker(), PCB_VIA_T, BOARD::Tracks(), and EDA_TEXT::TransformTextShapeToSegmentList().

Referenced by testCopperTextAndGraphics().

◆ testDisabledLayers()

void DRC::testDisabledLayers ( )
private

Tests for items placed on disabled layers (causing false connections).

Definition at line 1173 of file drc.cpp.

1174 {
1176  wxCHECK( board, /*void*/ );
1177  LSET disabledLayers = board->GetEnabledLayers().flip();
1178 
1179  // Perform the test only for copper layers
1180  disabledLayers &= LSET::AllCuMask();
1181 
1182  auto createMarker = [&]( BOARD_ITEM* aItem ) {
1184  aItem->GetPosition(), aItem, DRCE_DISABLED_LAYER_ITEM ) );
1185  };
1186 
1187  for( auto track : board->Tracks() )
1188  {
1189  if( disabledLayers.test( track->GetLayer() ) )
1190  createMarker( track );
1191  }
1192 
1193  for( auto module : board->Modules() )
1194  {
1195  module->RunOnChildren( [&]( BOARD_ITEM* aItem )
1196  {
1197  if( disabledLayers.test( aItem->GetLayer() ) )
1198  createMarker( aItem );
1199  } );
1200  }
1201 
1202  for( auto zone : board->Zones() )
1203  {
1204  if( disabledLayers.test( zone->GetLayer() ) )
1205  createMarker( zone );
1206  }
1207 }
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:676
#define DRCE_DISABLED_LAYER_ITEM
item on a disabled layer
Definition: drc.h:96
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction)
Function RunOnChildren.
BOARD * board() const
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
Class LSET is a set of PCB_LAYER_IDs.
MODULES & Modules()
Definition: class_board.h:236
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:236
ZONE_CONTAINERS & Zones()
Definition: class_board.h:250
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:161
MODULE * module() const
BOARD * GetBoard() const
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
TRACKS & Tracks()
Definition: class_board.h:227

References addMarkerToPcb(), LSET::AllCuMask(), PCB_TOOL_BASE::board(), DRCE_DISABLED_LAYER_ITEM, PCB_BASE_FRAME::GetBoard(), BOARD::GetEnabledLayers(), BOARD_ITEM::GetLayer(), m_markerFactory, m_pcbEditorFrame, PCB_TOOL_BASE::module(), BOARD::Modules(), DRC_MARKER_FACTORY::NewMarker(), MODULE::RunOnChildren(), BOARD::Tracks(), and BOARD::Zones().

Referenced by RunTests().

◆ testDrilledHoles()

void DRC::testDrilledHoles ( )
private

Definition at line 686 of file drc.cpp.

687 {
688  int holeToHoleMin = m_pcb->GetDesignSettings().m_HoleToHoleMin;
689 
690  if( holeToHoleMin == 0 ) // No min setting turns testing off.
691  return;
692 
693  // Test drilled hole clearances to minimize drill bit breakage.
694  //
695  // Notes: slots are milled, so we're only concerned with circular holes
696  // microvias are laser-drilled, so we're only concerned with standard vias
697 
698  struct DRILLED_HOLE
699  {
700  wxPoint m_location;
701  int m_drillRadius;
702  BOARD_ITEM* m_owner;
703  };
704 
705  std::vector<DRILLED_HOLE> holes;
706  DRILLED_HOLE hole;
707 
708  for( MODULE* mod : m_pcb->Modules() )
709  {
710  for( D_PAD* pad : mod->Pads( ) )
711  {
712  if( pad->GetDrillSize().x && pad->GetDrillShape() == PAD_DRILL_SHAPE_CIRCLE )
713  {
714  hole.m_location = pad->GetPosition();
715  hole.m_drillRadius = pad->GetDrillSize().x / 2;
716  hole.m_owner = pad;
717  holes.push_back( hole );
718  }
719  }
720  }
721 
722  for( TRACK* track : m_pcb->Tracks() )
723  {
724  VIA* via = dynamic_cast<VIA*>( track );
725  if( via && via->GetViaType() == VIA_THROUGH )
726  {
727  hole.m_location = via->GetPosition();
728  hole.m_drillRadius = via->GetDrillValue() / 2;
729  hole.m_owner = via;
730  holes.push_back( hole );
731  }
732  }
733 
734  for( size_t ii = 0; ii < holes.size(); ++ii )
735  {
736  const DRILLED_HOLE& refHole = holes[ ii ];
737 
738  for( size_t jj = ii + 1; jj < holes.size(); ++jj )
739  {
740  const DRILLED_HOLE& checkHole = holes[ jj ];
741 
742  // Holes with identical locations are allowable
743  if( checkHole.m_location == refHole.m_location )
744  continue;
745 
746  if( KiROUND( GetLineLength( checkHole.m_location, refHole.m_location ) )
747  < checkHole.m_drillRadius + refHole.m_drillRadius + holeToHoleMin )
748  {
750  DRCE_DRILLED_HOLES_TOO_CLOSE, refHole.m_location,
751  refHole.m_owner, refHole.m_location,
752  checkHole.m_owner, checkHole.m_location ) );
753  }
754  }
755  }
756 }
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:202
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
#define DRCE_DRILLED_HOLES_TOO_CLOSE
overlapping drilled holes break drill bits
Definition: drc.h:97
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:540
BOARD * m_pcb
Definition: drc.h:237
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
int m_HoleToHoleMin
Min width of peninsula between two drilled holes.
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
MODULES & Modules()
Definition: class_board.h:236
VIATYPE_T GetViaType() const
Definition: class_track.h:346
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:236
const wxPoint GetPosition() const override
Definition: class_track.h:319
EDA_UNITS_T GetUserUnits() const
Return the user units currently in use.
#define mod(a, n)
Definition: greymap.cpp:24
TRACKS & Tracks()
Definition: class_board.h:227
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:114

References addMarkerToPcb(), DRCE_DRILLED_HOLES_TOO_CLOSE, BOARD::GetDesignSettings(), VIA::GetDrillValue(), GetLineLength(), VIA::GetPosition(), EDA_BASE_FRAME::GetUserUnits(), VIA::GetViaType(), KiROUND(), BOARD_DESIGN_SETTINGS::m_HoleToHoleMin, m_pcb, m_pcbEditorFrame, mod, BOARD::Modules(), PAD_DRILL_SHAPE_CIRCLE, BOARD::Tracks(), and VIA_THROUGH.

Referenced by RunTests().

◆ TestFootprints()

void DRC::TestFootprints ( NETLIST aNetlist,
BOARD aPCB,
EDA_UNITS_T  aUnits,
DRC_LIST aDRCList 
)
static

Test the board footprints against a netlist.

Will report DRCE_MISSING_FOOTPRINT, DRCE_DUPLICATE_FOOTPRINT and DRCE_EXTRA_FOOTPRINT errors in aDRCList.

Definition at line 1351 of file drc.cpp.

1353 {
1354 
1355  // Search for duplicate footprints on the board
1356  auto comp = []( const MODULE* x, const MODULE* y ) {
1357  return x->GetReference().CmpNoCase( y->GetReference() ) < 0;
1358  };
1359  auto mods = std::set<MODULE*, decltype( comp )>( comp );
1360 
1361  for( auto mod : aPCB->Modules() )
1362  {
1363  auto ins = mods.insert( mod );
1364  if( !ins.second )
1365  {
1366  aDRCList.emplace_back( new DRC_ITEM( aUnits, DRCE_DUPLICATE_FOOTPRINT, mod,
1367  mod->GetPosition(), *ins.first, ( *ins.first )->GetPosition() ) );
1368  }
1369  }
1370 
1371  // Search for component footprints in the netlist but not on the board.
1372  for( unsigned ii = 0; ii < aNetlist.GetCount(); ii++ )
1373  {
1374  COMPONENT* component = aNetlist.GetComponent( ii );
1375 
1376  auto module = aPCB->FindModuleByReference( component->GetReference() );
1377 
1378  if( module == NULL )
1379  {
1380  wxString msg = wxString::Format( wxT( "%s (%s)" ),
1381  component->GetReference(),
1382  component->GetValue() );
1383 
1384  aDRCList.emplace_back( new DRC_ITEM( DRCE_MISSING_FOOTPRINT, msg ) );
1385  }
1386  }
1387 
1388  // Search for component footprints found on board but not in netlist.
1389  for( auto module : mods )
1390  {
1391  COMPONENT* component = aNetlist.GetComponentByReference( module->GetReference() );
1392 
1393  if( component == NULL )
1394  {
1395  aDRCList.emplace_back( new DRC_ITEM( aUnits, DRCE_EXTRA_FOOTPRINT,
1397  nullptr, wxPoint() ) );
1398  }
1399  }
1400 }
#define DRCE_EXTRA_FOOTPRINT
netlist item not found for footprint
Definition: drc.h:102
Class DRC_ITEM is a holder for a DRC (in Pcbnew) or ERC (in Eeschema) error item.
Definition: drc_item.h:48
#define DRCE_MISSING_FOOTPRINT
footprint not found for netlist item
Definition: drc.h:100
unsigned GetCount() const
Function GetCount.
Definition: pcb_netlist.h:256
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:416
#define DRCE_DUPLICATE_FOOTPRINT
more than one footprints found for netlist item
Definition: drc.h:101
MODULES & Modules()
Definition: class_board.h:236
const wxString & GetReference() const
Definition: pcb_netlist.h:151
Class COMPONENT is used to store components and all of their related information found in a netlist.
Definition: pcb_netlist.h:83
COMPONENT * GetComponent(unsigned aIndex)
Function GetComponent returns the COMPONENT at aIndex.
Definition: pcb_netlist.h:265
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
MODULE * module() const
MODULE * FindModuleByReference(const wxString &aReference) const
Function FindModuleByReference searches for a MODULE within this board with the given reference desig...
const wxString & GetValue() const
Definition: pcb_netlist.h:153
COMPONENT * GetComponentByReference(const wxString &aReference)
Function GetComponentByReference returns a COMPONENT by aReference.
const wxPoint GetPosition() const override
Definition: class_module.h:197
#define mod(a, n)
Definition: greymap.cpp:24

References DRCE_DUPLICATE_FOOTPRINT, DRCE_EXTRA_FOOTPRINT, DRCE_MISSING_FOOTPRINT, BOARD::FindModuleByReference(), Format(), NETLIST::GetComponent(), NETLIST::GetComponentByReference(), NETLIST::GetCount(), MODULE::GetPosition(), COMPONENT::GetReference(), MODULE::GetReference(), COMPONENT::GetValue(), mod, PCB_TOOL_BASE::module(), and BOARD::Modules().

Referenced by DIALOG_NETLIST::OnTestFootprintsClick(), and RunTests().

◆ testKeepoutAreas()

void DRC::testKeepoutAreas ( )
private

Definition at line 883 of file drc.cpp.

884 {
885  // Test keepout areas for vias, tracks and pads inside keepout areas
886  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
887  {
888  ZONE_CONTAINER* area = m_pcb->GetArea( ii );
889 
890  if( !area->GetIsKeepout() )
891  continue;
892 
893  for( auto segm : m_pcb->Tracks() )
894  {
895  if( segm->Type() == PCB_TRACE_T )
896  {
897  if( !area->GetDoNotAllowTracks() )
898  continue;
899 
900  // Ignore if the keepout zone is not on the same layer
901  if( !area->IsOnLayer( segm->GetLayer() ) )
902  continue;
903 
904  SEG trackSeg( segm->GetStart(), segm->GetEnd() );
905 
906  if( area->Outline()->Distance( trackSeg, segm->GetWidth() ) == 0 )
909  }
910  else if( segm->Type() == PCB_VIA_T )
911  {
912  if( ! area->GetDoNotAllowVias() )
913  continue;
914 
915  auto viaLayers = segm->GetLayerSet();
916 
917  if( !area->CommonLayerExists( viaLayers ) )
918  continue;
919 
920  if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 )
923  }
924  }
925  // Test pads: TODO
926  }
927 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:57
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:209
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:279
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:237
#define DRCE_VIA_INSIDE_KEEPOUT
Via in inside a keepout area.
Definition: drc.h:83
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
BOARD * m_pcb
Definition: drc.h:237
bool GetDoNotAllowVias() const
Definition: class_zone.h:623
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:955
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:621
Definition: seg.h:36
int Distance(VECTOR2I aPoint)
Function DistanceToPolygon computes the minimum distance between aPoint and all the polygons in the s...
#define DRCE_TRACK_INSIDE_KEEPOUT
Track in inside a keepout area.
Definition: drc.h:84
bool GetDoNotAllowTracks() const
Definition: class_zone.h:624
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:926
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
TRACKS & Tracks()
Definition: class_board.h:227

References addMarkerToPcb(), ZONE_CONTAINER::CommonLayerExists(), SHAPE_POLY_SET::Distance(), DRCE_TRACK_INSIDE_KEEPOUT, DRCE_VIA_INSIDE_KEEPOUT, BOARD::GetArea(), BOARD::GetAreaCount(), ZONE_CONTAINER::GetDoNotAllowTracks(), ZONE_CONTAINER::GetDoNotAllowVias(), ZONE_CONTAINER::GetIsKeepout(), ZONE_CONTAINER::IsOnLayer(), m_markerFactory, m_pcb, DRC_MARKER_FACTORY::NewMarker(), ZONE_CONTAINER::Outline(), PCB_TRACE_T, PCB_VIA_T, and BOARD::Tracks().

Referenced by RunTests().

◆ testNetClasses()

bool DRC::testNetClasses ( )
private

Go 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 624 of file drc.cpp.

625 {
626  bool ret = true;
627 
629 
630  wxString msg; // construct this only once here, not in a loop, since somewhat expensive.
631 
632  if( !doNetClass( netclasses.GetDefault(), msg ) )
633  ret = false;
634 
635  for( NETCLASSES::const_iterator i = netclasses.begin(); i != netclasses.end(); ++i )
636  {
637  NETCLASSPTR nc = i->second;
638 
639  if( !doNetClass( nc, msg ) )
640  ret = false;
641  }
642 
643  return ret;
644 }
bool doNetClass(const std::shared_ptr< NETCLASS > &aNetClass, wxString &msg)
Definition: drc.cpp:539
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:540
iterator end()
Definition: netclass.h:249
NETCLASS_MAP::const_iterator const_iterator
Definition: netclass.h:251
BOARD * m_pcb
Definition: drc.h:237
iterator begin()
Definition: netclass.h:248
Class NETCLASSES is a container for NETCLASS instances.
Definition: netclass.h:224
size_t i
Definition: json11.cpp:597
NETCLASSPTR GetDefault() const
Function GetDefault.
Definition: netclass.h:268

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

Referenced by RunTests().

◆ testOutline()

void DRC::testOutline ( )
private

Test that the board outline is contiguous and composed of valid elements.

Definition at line 1159 of file drc.cpp.

1160 {
1161  wxPoint error_loc( m_pcb->GetBoardEdgesBoundingBox().GetPosition() );
1162 
1164 
1165  if( !m_pcb->GetBoardPolygonOutlines( m_board_outlines, nullptr, &error_loc ) )
1166  {
1168  return;
1169  }
1170 }
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:804
BOARD * m_pcb
Definition: drc.h:237
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
const wxPoint GetPosition() const
Definition: eda_rect.h:115
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
#define DRCE_INVALID_OUTLINE
invalid board outline
Definition: drc.h:99
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, wxString *aErrorText=nullptr, wxPoint *aErrorLocation=nullptr)
Function GetBoardPolygonOutlines Extracts the board outlines and build a closed polygon from lines,...
SHAPE_POLY_SET m_board_outlines
The board outline including cutouts.
Definition: drc.h:238
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240

References addMarkerToPcb(), DRCE_INVALID_OUTLINE, BOARD::GetBoardEdgesBoundingBox(), BOARD::GetBoardPolygonOutlines(), EDA_RECT::GetPosition(), m_board_outlines, m_markerFactory, m_pcb, DRC_MARKER_FACTORY::NewMarker(), and SHAPE_POLY_SET::RemoveAllContours().

Referenced by RunTests().

◆ testPad2Pad()

void DRC::testPad2Pad ( )
private

Definition at line 647 of file drc.cpp.

648 {
649  std::vector<D_PAD*> sortedPads;
650 
651  m_pcb->GetSortedPadListByXthenYCoord( sortedPads );
652 
653  if( sortedPads.empty() )
654  return;
655 
656  // find the max size of the pads (used to stop the test)
657  int max_size = 0;
658 
659  for( D_PAD* pad : sortedPads )
660  {
661  // GetBoundingRadius() is the radius of the minimum sized circle fully containing the pad
662  int radius = pad->GetBoundingRadius();
663 
664  if( radius > max_size )
665  max_size = radius;
666  }
667 
668  // Upper limit of pad list (limit not included)
669  D_PAD** listEnd = &sortedPads[0] + sortedPads.size();
670 
671  // Test the pads
672  for( auto& pad : sortedPads )
673  {
674  int x_limit = pad->GetClearance() + pad->GetBoundingRadius() + pad->GetPosition().x;
675 
676  if( !doPadToPadsDrc( pad, &pad, listEnd, max_size + x_limit ) )
677  {
678  wxASSERT( m_currentMarker );
680  m_currentMarker = nullptr;
681  }
682  }
683 }
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.h:237
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
bool doPadToPadsDrc(D_PAD *aRefPad, D_PAD **aStart, D_PAD **aEnd, int x_limit)
Test the clearance between aRefPad and other pads.
Definition: drc.cpp:1210
MARKER_PCB * m_currentMarker
Definition: drc.h:211
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_pad.cpp:596

References addMarkerToPcb(), doPadToPadsDrc(), D_PAD::GetClearance(), BOARD::GetSortedPadListByXthenYCoord(), m_currentMarker, and m_pcb.

Referenced by RunTests().

◆ testTracks()

void DRC::testTracks ( wxWindow *  aActiveWindow,
bool  aShowProgressBar 
)
private

Perform the DRC on all tracks.

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 759 of file drc.cpp.

760 {
761  wxProgressDialog * progressDialog = NULL;
762  const int delta = 500; // This is the number of tests between 2 calls to the
763  // progress bar
764  int count = m_pcb->Tracks().size();
765 
766  int deltamax = count/delta;
767 
768  if( aShowProgressBar && deltamax > 3 )
769  {
770  // Do not use wxPD_APP_MODAL style here: it is not necessary and create issues
771  // on OSX
772  progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString,
773  deltamax, aActiveWindow,
774  wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME );
775  progressDialog->Update( 0, wxEmptyString );
776  }
777 
778  int ii = 0;
779  count = 0;
780 
781  for( auto seg_it = m_pcb->Tracks().begin(); seg_it != m_pcb->Tracks().end(); seg_it++ )
782  {
783  if( ii++ > delta )
784  {
785  ii = 0;
786  count++;
787 
788  if( progressDialog )
789  {
790  if( !progressDialog->Update( count, wxEmptyString ) )
791  break; // Aborted by user
792 #ifdef __WXMAC__
793  // Work around a dialog z-order issue on OS X
794  if( count == deltamax )
795  aActiveWindow->Raise();
796 #endif
797  }
798  }
799 
800  // Test new segment against tracks and pads, optionally against copper zones
801  if( !doTrackDrc( *seg_it, seg_it + 1, m_pcb->Tracks().end(), m_doZonesTest ) )
802  {
803  if( m_currentMarker )
804  {
806  m_currentMarker = nullptr;
807  }
808  }
809  }
810 
811  if( progressDialog )
812  progressDialog->Destroy();
813 }
bool doTrackDrc(TRACK *aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterator aEndIt, bool aTestZones)
Test the current segment.
BOARD * m_pcb
Definition: drc.h:237
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
bool m_doZonesTest
Definition: drc.h:202
#define _(s)
MARKER_PCB * m_currentMarker
Definition: drc.h:211
TRACKS & Tracks()
Definition: class_board.h:227

References _, addMarkerToPcb(), doTrackDrc(), m_currentMarker, m_doZonesTest, m_pcb, and BOARD::Tracks().

Referenced by RunTests().

◆ testUnconnected()

void DRC::testUnconnected ( )
private

Definition at line 816 of file drc.cpp.

817 {
818  for( DRC_ITEM* unconnectedItem : m_unconnected )
819  delete unconnectedItem;
820 
821  m_unconnected.clear();
822 
823  auto connectivity = m_pcb->GetConnectivity();
824 
825  connectivity->Clear();
826  connectivity->Build( m_pcb ); // just in case. This really needs to be reliable.
827  connectivity->RecalculateRatsnest();
828 
829  std::vector<CN_EDGE> edges;
830  connectivity->GetUnconnectedEdges( edges );
831 
832  for( const auto& edge : edges )
833  {
834  auto src = edge.GetSourcePos();
835  auto dst = edge.GetTargetPos();
836 
837  m_unconnected.emplace_back( new DRC_ITEM( m_pcbEditorFrame->GetUserUnits(),
839  edge.GetSourceNode()->Parent(),
840  wxPoint( src.x, src.y ),
841  edge.GetTargetNode()->Parent(),
842  wxPoint( dst.x, dst.y ) ) );
843  }
844 }
Class DRC_ITEM is a holder for a DRC (in Pcbnew) or ERC (in Eeschema) error item.
Definition: drc_item.h:48
#define DRCE_UNCONNECTED_ITEMS
items are unconnected
Definition: drc.h:47
BOARD * m_pcb
Definition: drc.h:237
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:310
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:236
EDA_UNITS_T GetUserUnits() const
Return the user units currently in use.
DRC_LIST m_unconnected
list of unconnected pads, as DRC_ITEMs
Definition: drc.h:242

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

Referenced by RunTests().

◆ testZones()

void DRC::testZones ( )
private

Definition at line 847 of file drc.cpp.

848 {
849  // Test copper areas for valid netcodes
850  // if a netcode is < 0 the netname was not found when reading a netlist
851  // if a netcode is == 0 the netname is void, and the zone is not connected.
852  // This is allowed, but i am not sure this is a good idea
853  //
854  // In recent Pcbnew versions, the netcode is always >= 0, but an internal net name
855  // is stored, and initialized from the file or the zone properties editor.
856  // if it differs from the net name from net code, there is a DRC issue
857  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
858  {
859  ZONE_CONTAINER* zone = m_pcb->GetArea( ii );
860 
861  if( !zone->IsOnCopperLayer() )
862  continue;
863 
864  int netcode = zone->GetNetCode();
865  // a netcode < 0 or > 0 and no pad in net is a error or strange
866  // perhaps a "dead" net, which happens when all pads in this net were removed
867  // Remark: a netcode < 0 should not happen (this is more a bug somewhere)
868  int pads_in_net = ( netcode > 0 ) ? m_pcb->GetConnectivity()->GetPadCount( netcode ) : 1;
869 
870  if( ( netcode < 0 ) || pads_in_net == 0 )
871  {
872  wxPoint markerPos = zone->GetPosition();
873  addMarkerToPcb( m_markerFactory.NewMarker( markerPos, zone,
875  }
876  }
877 
878  // Test copper areas outlines, and create markers when needed
879  TestZoneToZoneOutline( NULL, true );
880 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:57
int GetNetCode() const
Function GetNetCode.
int TestZoneToZoneOutline(ZONE_CONTAINER *aZone, bool aCreateMarkers)
Tests whether distance between zones complies with the DRC rules.
Definition: drc.cpp:184
const wxPoint GetPosition() const override
Definition: class_zone.cpp:184
#define DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE
copper area has a net but no pads in nets, which is suspicious
Definition: drc.h:69
BOARD * m_pcb
Definition: drc.h:237
void addMarkerToPcb(MARKER_PCB *aMarker)
Adds a DRC marker to the PCB through the COMMIT mechanism.
Definition: drc.cpp:164
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:955
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Function GetConnectivity() returns list of missing connections between components/tracks.
Definition: class_board.h:310
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:926
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
bool IsOnCopperLayer() const override
Function IsOnCopperLayer.
Definition: class_zone.cpp:196

References addMarkerToPcb(), DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE, BOARD::GetArea(), BOARD::GetAreaCount(), BOARD::GetConnectivity(), BOARD_CONNECTED_ITEM::GetNetCode(), ZONE_CONTAINER::GetPosition(), ZONE_CONTAINER::IsOnCopperLayer(), m_markerFactory, m_pcb, DRC_MARKER_FACTORY::NewMarker(), and TestZoneToZoneOutline().

Referenced by RunTests().

◆ TestZoneToZoneOutline()

int DRC::TestZoneToZoneOutline ( ZONE_CONTAINER aZone,
bool  aCreateMarkers 
)

Tests whether distance between zones complies with the DRC rules.

Parameters
aZonezone to compare with other zones, or if NULL then all zones are compared to all others.
aCreateMarkersif true create DRC markers. False: do not create markers. only fing drc errors
Returns
Errors count

Definition at line 184 of file drc.cpp.

185 {
187  BOARD_COMMIT commit( m_pcbEditorFrame );
188  int nerrors = 0;
189 
190  std::vector<SHAPE_POLY_SET> smoothed_polys;
191  smoothed_polys.resize( board->GetAreaCount() );
192 
193  for( int ia = 0; ia < board->GetAreaCount(); ia++ )
194  {
195  ZONE_CONTAINER* zoneRef = board->GetArea( ia );
196  std::set<VECTOR2I> colinearCorners;
197  zoneRef->GetColinearCorners( board, colinearCorners );
198 
199  zoneRef->BuildSmoothedPoly( smoothed_polys[ia], &colinearCorners );
200  }
201 
202  // iterate through all areas
203  for( int ia = 0; ia < board->GetAreaCount(); ia++ )
204  {
205  ZONE_CONTAINER* zoneRef = board->GetArea( ia );
206 
207  if( !zoneRef->IsOnCopperLayer() )
208  continue;
209 
210  // When testing only a single area, skip all others
211  if( aZone && ( aZone != zoneRef) )
212  continue;
213 
214  // If we are testing a single zone, then iterate through all other zones
215  // Otherwise, we have already tested the zone combination
216  for( int ia2 = ( aZone ? 0 : ia + 1 ); ia2 < board->GetAreaCount(); ia2++ )
217  {
218  ZONE_CONTAINER* zoneToTest = board->GetArea( ia2 );
219 
220  if( zoneRef == zoneToTest )
221  continue;
222 
223  // test for same layer
224  if( zoneRef->GetLayer() != zoneToTest->GetLayer() )
225  continue;
226 
227  // Test for same net
228  if( zoneRef->GetNetCode() == zoneToTest->GetNetCode() && zoneRef->GetNetCode() >= 0 )
229  continue;
230 
231  // test for different priorities
232  if( zoneRef->GetPriority() != zoneToTest->GetPriority() )
233  continue;
234 
235  // test for different types
236  if( zoneRef->GetIsKeepout() != zoneToTest->GetIsKeepout() )
237  continue;
238 
239  // Examine a candidate zone: compare zoneToTest to zoneRef
240 
241  // Get clearance used in zone to zone test. The policy used to
242  // obtain that value is now part of the zone object itself by way of
243  // ZONE_CONTAINER::GetClearance().
244  int zone2zoneClearance = zoneRef->GetClearance( zoneToTest );
245 
246  // Keepout areas have no clearance, so set zone2zoneClearance to 1
247  // ( zone2zoneClearance = 0 can create problems in test functions)
248  if( zoneRef->GetIsKeepout() )
249  zone2zoneClearance = 1;
250 
251  // test for some corners of zoneRef inside zoneToTest
252  for( auto iterator = smoothed_polys[ia].IterateWithHoles(); iterator; iterator++ )
253  {
254  VECTOR2I currentVertex = *iterator;
255  wxPoint pt( currentVertex.x, currentVertex.y );
256 
257  if( smoothed_polys[ia2].Contains( currentVertex ) )
258  {
259  if( aCreateMarkers )
260  commit.Add( m_markerFactory.NewMarker( pt, zoneRef, zoneToTest,
262 
263  nerrors++;
264  }
265  }
266 
267  // test for some corners of zoneToTest inside zoneRef
268  for( auto iterator = smoothed_polys[ia2].IterateWithHoles(); iterator; iterator++ )
269  {
270  VECTOR2I currentVertex = *iterator;
271  wxPoint pt( currentVertex.x, currentVertex.y );
272 
273  if( smoothed_polys[ia].Contains( currentVertex ) )
274  {
275  if( aCreateMarkers )
276  commit.Add( m_markerFactory.NewMarker( pt, zoneToTest, zoneRef,
278 
279  nerrors++;
280  }
281  }
282 
283  // Iterate through all the segments of refSmoothedPoly
284  std::set<wxPoint> conflictPoints;
285 
286  for( auto refIt = smoothed_polys[ia].IterateSegmentsWithHoles(); refIt; refIt++ )
287  {
288  // Build ref segment
289  SEG refSegment = *refIt;
290 
291  // Iterate through all the segments in smoothed_polys[ia2]
292  for( auto testIt = smoothed_polys[ia2].IterateSegmentsWithHoles(); testIt; testIt++ )
293  {
294  // Build test segment
295  SEG testSegment = *testIt;
296  wxPoint pt;
297 
298  int ax1, ay1, ax2, ay2;
299  ax1 = refSegment.A.x;
300  ay1 = refSegment.A.y;
301  ax2 = refSegment.B.x;
302  ay2 = refSegment.B.y;
303 
304  int bx1, by1, bx2, by2;
305  bx1 = testSegment.A.x;
306  by1 = testSegment.A.y;
307  bx2 = testSegment.B.x;
308  by2 = testSegment.B.y;
309 
310  int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
311  0,
312  ax1, ay1, ax2, ay2,
313  0,
314  zone2zoneClearance,
315  &pt.x, &pt.y );
316 
317  if( d < zone2zoneClearance )
318  conflictPoints.insert( pt );
319  }
320  }
321 
322  for( wxPoint pt : conflictPoints )
323  {
324  if( aCreateMarkers )
325  commit.Add( m_markerFactory.NewMarker( pt, zoneRef, zoneToTest,
327 
328  nerrors++;
329  }
330  }
331  }
332 
333  if( aCreateMarkers )
334  commit.Push( wxEmptyString, false, false );
335 
336  return nerrors;
337 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:57
int GetNetCode() const
Function GetNetCode.
BOARD * board() const
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:190
#define DRCE_ZONES_INTERSECT
copper area outlines intersect
Definition: drc.h:67
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_zone.cpp:628
void GetColinearCorners(BOARD *aBoard, std::set< VECTOR2I > &colinearCorners)
Some intersecting zones, despite being on the same layer with the same net, cannot be merged due to o...
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:955
bool BuildSmoothedPoly(SHAPE_POLY_SET &aSmoothedPoly, std::set< VECTOR2I > *aPreserveCorners) const
Function GetSmoothedPoly returns a pointer to the corner-smoothed version of m_Poly.
MARKER_PCB * NewMarker(TRACK *aTrack, BOARD_ITEM *aConflitItem, const SEG &aConflictSeg, int aErrorCode) const
Creates a marker on a track, via or pad.
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)
PCB_EDIT_FRAME * m_pcbEditorFrame
The pcb frame editor which owns the board.
Definition: drc.h:236
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:621
Definition: seg.h:36
unsigned GetPriority() const
Function GetPriority.
Definition: class_zone.h:94
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:161
VECTOR2I A
Definition: seg.h:44
#define DRCE_ZONES_TOO_CLOSE
copper area outlines are too close
Definition: drc.h:68
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:926
BOARD * GetBoard() const
DRC_MARKER_FACTORY m_markerFactory
Class that generates markers.
Definition: drc.h:240
bool IsOnCopperLayer() const override
Function IsOnCopperLayer.
Definition: class_zone.cpp:196
VECTOR2I B
Definition: seg.h:45

References SEG::A, COMMIT::Add(), SEG::B, PCB_TOOL_BASE::board(), ZONE_CONTAINER::BuildSmoothedPoly(), DRCE_ZONES_INTERSECT, DRCE_ZONES_TOO_CLOSE, BOARD::GetArea(), BOARD::GetAreaCount(), PCB_BASE_FRAME::GetBoard(), ZONE_CONTAINER::GetClearance(), GetClearanceBetweenSegments(), ZONE_CONTAINER::GetColinearCorners(), ZONE_CONTAINER::GetIsKeepout(), ZONE_CONTAINER::GetLayer(), BOARD_CONNECTED_ITEM::GetNetCode(), ZONE_CONTAINER::GetPriority(), ZONE_CONTAINER::IsOnCopperLayer(), m_markerFactory, m_pcbEditorFrame, DRC_MARKER_FACTORY::NewMarker(), BOARD_COMMIT::Push(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by testZones().

◆ updatePointers()

void DRC::updatePointers ( )
private

Update needed pointers from the one pointer which is known not to change.

Definition at line 520 of file drc.cpp.

521 {
522  // update my pointers, m_pcbEditorFrame is the only unchangeable one
524 
525  if( m_drcDialog ) // Use diag list boxes only in DRC dialog
526  {