From b365f17e9fa64c29b7d570cbcd50a785f1a67126 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Thu, 16 Mar 2017 18:09:33 +0100 Subject: [PATCH] First draft of courtyard overlap detection. --- pcbnew/class_drc_item.cpp | 6 + pcbnew/class_module.cpp | 74 + pcbnew/class_module.h | 16 + pcbnew/class_pad.h | 4 +- pcbnew/dialogs/dialog_drc.cpp | 28 +- pcbnew/dialogs/dialog_drc.h | 3 +- pcbnew/dialogs/dialog_drc_base.cpp | 118 +- pcbnew/dialogs/dialog_drc_base.fbp | 2057 +++++++++++++++++----------- pcbnew/dialogs/dialog_drc_base.h | 10 +- pcbnew/drc.cpp | 85 +- pcbnew/drc_marker_functions.cpp | 17 +- pcbnew/drc_stuff.h | 33 +- 12 files changed, 1562 insertions(+), 889 deletions(-) diff --git a/pcbnew/class_drc_item.cpp b/pcbnew/class_drc_item.cpp index cf92901a7f..f9e7714d36 100644 --- a/pcbnew/class_drc_item.cpp +++ b/pcbnew/class_drc_item.cpp @@ -126,6 +126,12 @@ wxString DRC_ITEM::GetErrorText() const case DRCE_PAD_INSIDE_TEXT: return wxString( _( "Pad inside a text" ) ); + case DRCE_OVERLAPPING_FOOTPRINTS: + return wxString( _( "Courtyards overlap" ) ); + + case DRCE_MISSING_COURTYARD_IN_FOOTPRINT: + return wxString( _( "Footprint has no courtard defined" ) ); + default: return wxString::Format( wxT( "Unknown DRC error code %d" ), m_ErrorCode ); } diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 07b992385b..13fa828d68 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -1219,3 +1220,76 @@ double MODULE::PadCoverageRatio() const return std::min( ratio, 1.0 ); } + + +bool MODULE::BuildPolyCourtyard() +{ + m_poly_courtyard.RemoveAllContours(); + // Build the courtyard area from graphic items on the courtyard. + // Only PCB_MODULE_EDGE_T have meaning, graphic texts are ignored. + // Collect items: + std::vector< EDGE_MODULE* > list; + + for( BOARD_ITEM* item = GraphicalItems(); item; item = item->Next() ) + { + if( item->GetLayer() == B_CrtYd && item->Type() == PCB_MODULE_EDGE_T ) + list.push_back( static_cast< EDGE_MODULE* > ( item ) ); + + if( item->GetLayer() == F_CrtYd && item->Type() == PCB_MODULE_EDGE_T ) + list.push_back( static_cast< EDGE_MODULE* > ( item ) ); + } + + if( !list.size() ) + return false; + + // Build the coutyard + const int circleToSegmentsCount = 16; + EDA_RECT rect; // the bouding box of segments + bool has_segments = false; + + for( EDGE_MODULE* item : list ) + { + switch( item->GetShape() ) + { + case S_SEGMENT: + if( !has_segments ) + { + rect.Move( item->GetStart() ); + has_segments = true; + } + else + rect.Merge( item->GetStart() ); + + rect.Merge( item->GetEnd() ); + break; + + case S_CIRCLE: + TransformCircleToPolygon( m_poly_courtyard, item->GetCenter(), + item->GetRadius(), circleToSegmentsCount ); + break; + + case S_ARC: + break; + + case S_POLYGON: + break; + + default: + break; + } + } + + if( has_segments ) // Build the polygon from bounding box + { + m_poly_courtyard.NewOutline(); + m_poly_courtyard.Append( rect.GetOrigin().x, rect.GetOrigin().y ); + m_poly_courtyard.Append( rect.GetOrigin().x + rect.GetWidth(), + rect.GetOrigin().y ); + m_poly_courtyard.Append( rect.GetOrigin().x + rect.GetWidth(), + rect.GetOrigin().y + rect.GetHeight() ); + m_poly_courtyard.Append( rect.GetOrigin().x, + rect.GetOrigin().y + rect.GetHeight() ); + } + + return true; +} diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index e64448109e..2ebfe97d95 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -640,6 +640,19 @@ public: /// Return the initial comments block or NULL if none, without transfer of ownership. const wxArrayString* GetInitialComments() const { return m_initial_comments; } + /** Used in DRC to test the courtyard area (a complex polygon) + * @return the courtyard polygon + */ + SHAPE_POLY_SET& GetPolyCourtyard() { return m_poly_courtyard; } + + /** Used in DRC to build the courtyard area (a complex polygon) + * from graphic items put on the courtyard + * @return true if OK, false if the polygon cannot be built + * The polygon cannot be built if segments/arcs on courtyard layers + * cannot be grouped in a polygon. + */ + bool BuildPolyCourtyard(); + #if defined(DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); } #endif @@ -682,6 +695,9 @@ private: wxArrayString* m_initial_comments; ///< leading s-expression comments in the module, ///< lazily allocated only if needed for speed + + /// Used in DRC to test the courtyard area (a polygon which can be not basic + SHAPE_POLY_SET m_poly_courtyard; }; #endif // MODULE_H_ diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 669746bd53..8b928ebec0 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2016 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index 8ea11582bc..4330980481 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -5,9 +5,9 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2009-2016 Dick Hollenbeck, dick@softplc.com - * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -28,6 +28,7 @@ */ #include +#include #include #include #include @@ -42,10 +43,16 @@ * and run DRC tests */ +// Keywords for read and write config +#define TestMissingCourtyardKey wxT( "TestMissingCourtyard" ) +#define TestFootprintCourtyardKey wxT( "TestFootprintCourtyard" ) + + DIALOG_DRC_CONTROL::DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ) : DIALOG_DRC_CONTROL_BASE( aParent ) { + m_config = Kiface().KifaceSettings(); m_tester = aTester; m_brdEditor = aEditorFrame; m_currentBoard = m_brdEditor->GetBoard(); @@ -57,6 +64,11 @@ DIALOG_DRC_CONTROL::DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* aEditorFra FinishDialogSettings(); } +DIALOG_DRC_CONTROL::~DIALOG_DRC_CONTROL() +{ + m_config->Write( TestMissingCourtyardKey, m_cbCourtyardMissing->GetValue() ); + m_config->Write( TestFootprintCourtyardKey, m_cbCourtyardOverlap->GetValue() ); +} void DIALOG_DRC_CONTROL::OnActivateDlg( wxActivateEvent& event ) { @@ -111,6 +123,14 @@ void DIALOG_DRC_CONTROL::InitValues() DisplayDRCValues(); + // read options + bool value; + m_config->Read( TestMissingCourtyardKey, &value, false ); + m_cbCourtyardMissing->SetValue( value ); + m_config->Read( TestFootprintCourtyardKey, &value, false ); + m_cbCourtyardOverlap->SetValue( value ); + + // Set the initial "enabled" status of the browse button and the text // field for report name wxCommandEvent junk; @@ -172,6 +192,8 @@ void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event ) true, // unconnected pads DRC test enabled true, // DRC test for zones enabled true, // DRC test for keepout areas enabled + m_cbCourtyardOverlap->GetValue(), + m_cbCourtyardMissing->GetValue(), reportName, make_report ); DelDRCMarkers(); @@ -243,6 +265,8 @@ void DIALOG_DRC_CONTROL::OnListUnconnectedClick( wxCommandEvent& event ) true, // unconnected pads DRC test enabled true, // DRC test for zones enabled true, // DRC test for keepout areas enabled + m_cbCourtyardOverlap->GetValue(), + m_cbCourtyardMissing->GetValue(), reportName, make_report ); DelDRCMarkers(); diff --git a/pcbnew/dialogs/dialog_drc.h b/pcbnew/dialogs/dialog_drc.h index 61d4c7ac24..cd7682993e 100644 --- a/pcbnew/dialogs/dialog_drc.h +++ b/pcbnew/dialogs/dialog_drc.h @@ -58,7 +58,7 @@ public: /// Constructors DIALOG_DRC_CONTROL( DRC* aTester, PCB_EDIT_FRAME* aEditorFrame, wxWindow* aParent ); - ~DIALOG_DRC_CONTROL(){}; + ~DIALOG_DRC_CONTROL(); /** * Enable/disable the report file creation @@ -147,6 +147,7 @@ private: BOARD* m_currentBoard; // the board currently on test DRC* m_tester; PCB_EDIT_FRAME* m_brdEditor; + wxConfigBase* m_config; }; #endif // _DIALOG_DRC_H_ diff --git a/pcbnew/dialogs/dialog_drc_base.cpp b/pcbnew/dialogs/dialog_drc_base.cpp index 392c40c28c..cbc5b0a596 100644 --- a/pcbnew/dialogs/dialog_drc_base.cpp +++ b/pcbnew/dialogs/dialog_drc_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Feb 16 2016) +// C++ code generated with wxFormBuilder (version May 6 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -21,11 +21,23 @@ DIALOG_DRC_CONTROL_BASE::DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID i wxBoxSizer* m_CommandSizer; m_CommandSizer = new wxBoxSizer( wxHORIZONTAL ); - wxStaticBoxSizer* sbSizerOptions; - sbSizerOptions = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options:") ), wxHORIZONTAL ); + wxBoxSizer* bSizerOptions; + bSizerOptions = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer* bSizer7; - bSizer7 = new wxBoxSizer( wxVERTICAL ); + m_staticTextOptions = new wxStaticText( this, wxID_ANY, _("Options:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextOptions->Wrap( -1 ); + m_staticTextOptions->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); + + bSizerOptions->Add( m_staticTextOptions, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizerOptsSettings; + bSizerOptsSettings = new wxBoxSizer( wxHORIZONTAL ); + + + bSizerOptsSettings->Add( 20, 20, 0, 0, 5 ); + + wxBoxSizer* bSizerOptSettings; + bSizerOptSettings = new wxBoxSizer( wxVERTICAL ); wxFlexGridSizer* fgMinValuesSizer; fgMinValuesSizer = new wxFlexGridSizer( 4, 3, 0, 0 ); @@ -33,91 +45,121 @@ DIALOG_DRC_CONTROL_BASE::DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID i fgMinValuesSizer->SetFlexibleDirection( wxHORIZONTAL ); fgMinValuesSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - m_ClearanceTitle = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Clearance"), wxDefaultPosition, wxDefaultSize, 0 ); + m_ClearanceTitle = new wxStaticText( this, wxID_ANY, _("Clearance"), wxDefaultPosition, wxDefaultSize, 0 ); m_ClearanceTitle->Wrap( -1 ); - fgMinValuesSizer->Add( m_ClearanceTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + fgMinValuesSizer->Add( m_ClearanceTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT, 5 ); - m_SetClearance = new wxTextCtrl( sbSizerOptions->GetStaticBox(), wxID_ANY, _("By Netclass"), wxDefaultPosition, wxDefaultSize, 0 ); + m_SetClearance = new wxTextCtrl( this, wxID_ANY, _("By Netclass"), wxDefaultPosition, wxDefaultSize, 0 ); m_SetClearance->Enable( false ); - fgMinValuesSizer->Add( m_SetClearance, 0, wxALL|wxEXPAND, 5 ); + fgMinValuesSizer->Add( m_SetClearance, 0, wxEXPAND|wxALL, 5 ); - fgMinValuesSizer->Add( 0, 0, 1, wxEXPAND, 5 ); + fgMinValuesSizer->Add( 0, 0, 0, 0, 5 ); - m_TrackMinWidthTitle = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Min track width"), wxDefaultPosition, wxDefaultSize, 0 ); + m_TrackMinWidthTitle = new wxStaticText( this, wxID_ANY, _("Min track width"), wxDefaultPosition, wxDefaultSize, 0 ); m_TrackMinWidthTitle->Wrap( -1 ); m_TrackMinWidthTitle->SetToolTip( _("Enter the minimum acceptable value for a track width") ); - fgMinValuesSizer->Add( m_TrackMinWidthTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + fgMinValuesSizer->Add( m_TrackMinWidthTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT, 5 ); - m_SetTrackMinWidthCtrl = new wxTextCtrl( sbSizerOptions->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - fgMinValuesSizer->Add( m_SetTrackMinWidthCtrl, 0, wxALL|wxEXPAND, 5 ); + m_SetTrackMinWidthCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgMinValuesSizer->Add( m_SetTrackMinWidthCtrl, 0, wxEXPAND|wxALL, 5 ); - m_TrackMinWidthUnit = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); + m_TrackMinWidthUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_TrackMinWidthUnit->Wrap( -1 ); m_TrackMinWidthUnit->SetToolTip( _("Enter the minimum acceptable value for a track width") ); - fgMinValuesSizer->Add( m_TrackMinWidthUnit, 0, wxALL, 5 ); + fgMinValuesSizer->Add( m_TrackMinWidthUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_ViaMinTitle = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Min via size"), wxDefaultPosition, wxDefaultSize, 0 ); + m_ViaMinTitle = new wxStaticText( this, wxID_ANY, _("Min via size"), wxDefaultPosition, wxDefaultSize, 0 ); m_ViaMinTitle->Wrap( -1 ); m_ViaMinTitle->SetHelpText( _("Enter the minimum acceptable diameter for a standard via") ); - fgMinValuesSizer->Add( m_ViaMinTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + fgMinValuesSizer->Add( m_ViaMinTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT, 5 ); - m_SetViaMinSizeCtrl = new wxTextCtrl( sbSizerOptions->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_SetViaMinSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); fgMinValuesSizer->Add( m_SetViaMinSizeCtrl, 0, wxALL|wxEXPAND, 5 ); - m_ViaMinUnit = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); + m_ViaMinUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_ViaMinUnit->Wrap( -1 ); m_ViaMinUnit->SetHelpText( _("Enter the minimum acceptable diameter for a standard via") ); - fgMinValuesSizer->Add( m_ViaMinUnit, 0, wxALL, 5 ); + fgMinValuesSizer->Add( m_ViaMinUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_MicroViaMinTitle = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Min uVia size"), wxDefaultPosition, wxDefaultSize, 0 ); + m_MicroViaMinTitle = new wxStaticText( this, wxID_ANY, _("Min uVia size"), wxDefaultPosition, wxDefaultSize, 0 ); m_MicroViaMinTitle->Wrap( -1 ); m_MicroViaMinTitle->SetToolTip( _("Enter the minimum acceptable diameter for a micro via") ); - fgMinValuesSizer->Add( m_MicroViaMinTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + fgMinValuesSizer->Add( m_MicroViaMinTitle, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT, 5 ); - m_SetMicroViakMinSizeCtrl = new wxTextCtrl( sbSizerOptions->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_SetMicroViakMinSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); fgMinValuesSizer->Add( m_SetMicroViakMinSizeCtrl, 0, wxALL|wxEXPAND, 5 ); - m_MicroViaMinUnit = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); + m_MicroViaMinUnit = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 ); m_MicroViaMinUnit->Wrap( -1 ); m_MicroViaMinUnit->SetToolTip( _("Enter the minimum acceptable diameter for a micro via") ); - fgMinValuesSizer->Add( m_MicroViaMinUnit, 0, wxALL, 5 ); + fgMinValuesSizer->Add( m_MicroViaMinUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - bSizer7->Add( fgMinValuesSizer, 1, wxEXPAND, 5 ); + bSizerOptSettings->Add( fgMinValuesSizer, 0, wxEXPAND, 5 ); - wxStaticBoxSizer* ReportFileSizer; - ReportFileSizer = new wxStaticBoxSizer( new wxStaticBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Create Report File") ), wxHORIZONTAL ); + m_cbCourtyardOverlap = new wxCheckBox( this, wxID_ANY, _("Check footprint courtyard overlap"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerOptSettings->Add( m_cbCourtyardOverlap, 0, wxALL, 5 ); - m_CreateRptCtrl = new wxCheckBox( ReportFileSizer->GetStaticBox(), ID_CHECKBOX_RPT_FILE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_cbCourtyardMissing = new wxCheckBox( this, wxID_ANY, _("Check courtyard missing in footprints"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerOptSettings->Add( m_cbCourtyardMissing, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + bSizerOptsSettings->Add( bSizerOptSettings, 1, wxEXPAND, 5 ); + + + bSizerOptions->Add( bSizerOptsSettings, 1, wxEXPAND, 5 ); + + + bSizerOptions->Add( 10, 5, 0, 0, 5 ); + + m_staticTextRpt = new wxStaticText( this, wxID_ANY, _("Create Report File"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextRpt->Wrap( -1 ); + m_staticTextRpt->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); + + bSizerOptions->Add( m_staticTextRpt, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizerRpt; + bSizerRpt = new wxBoxSizer( wxHORIZONTAL ); + + + bSizerRpt->Add( 20, 20, 0, 0, 5 ); + + wxFlexGridSizer* fgSizerRpt; + fgSizerRpt = new wxFlexGridSizer( 0, 3, 0, 0 ); + fgSizerRpt->AddGrowableCol( 1 ); + fgSizerRpt->SetFlexibleDirection( wxBOTH ); + fgSizerRpt->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_CreateRptCtrl = new wxCheckBox( this, ID_CHECKBOX_RPT_FILE, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_CreateRptCtrl->SetToolTip( _("Enable writing report to this file") ); - ReportFileSizer->Add( m_CreateRptCtrl, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + fgSizerRpt->Add( m_CreateRptCtrl, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_RptFilenameCtrl = new wxTextCtrl( ReportFileSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_RptFilenameCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_RptFilenameCtrl->SetToolTip( _("Enter the report filename") ); m_RptFilenameCtrl->SetMinSize( wxSize( 180,-1 ) ); - ReportFileSizer->Add( m_RptFilenameCtrl, 1, wxALL|wxEXPAND, 5 ); + fgSizerRpt->Add( m_RptFilenameCtrl, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - m_BrowseButton = new wxButton( ReportFileSizer->GetStaticBox(), ID_BUTTON_BROWSE_RPT_FILE, _("..."), wxDefaultPosition, wxSize( 50,-1 ), 0 ); - ReportFileSizer->Add( m_BrowseButton, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_BrowseButton = new wxButton( this, ID_BUTTON_BROWSE_RPT_FILE, _("..."), wxDefaultPosition, wxSize( 50,-1 ), 0 ); + fgSizerRpt->Add( m_BrowseButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - bSizer7->Add( ReportFileSizer, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + bSizerRpt->Add( fgSizerRpt, 1, 0, 5 ); - sbSizerOptions->Add( bSizer7, 1, wxEXPAND, 5 ); + bSizerOptions->Add( bSizerRpt, 0, wxEXPAND, 5 ); - m_CommandSizer->Add( sbSizerOptions, 1, 0, 5 ); + m_CommandSizer->Add( bSizerOptions, 1, wxEXPAND, 5 ); wxBoxSizer* bSizerMessages; bSizerMessages = new wxBoxSizer( wxVERTICAL ); diff --git a/pcbnew/dialogs/dialog_drc_base.fbp b/pcbnew/dialogs/dialog_drc_base.fbp index a04ae0ba5a..71d9f4d2af 100644 --- a/pcbnew/dialogs/dialog_drc_base.fbp +++ b/pcbnew/dialogs/dialog_drc_base.fbp @@ -44,7 +44,7 @@ DIALOG_DRC_CONTROL_BASE - 733,438 + 679,518 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h DRC Control @@ -97,238 +97,1109 @@ 5 wxALL|wxEXPAND 0 - + m_CommandSizer wxHORIZONTAL none - + 5 - + wxEXPAND 1 - - wxID_ANY - Options: + - sbSizerOptions - wxHORIZONTAL - 1 + bSizerOptions + wxVERTICAL none - - + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,92,-1,70,0 + 0 + 0 + wxID_ANY + Options: + + 0 + + + 0 + + 1 + m_staticTextOptions + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + 5 wxEXPAND 1 - + - bSizer7 - wxVERTICAL + bSizerOptsSettings + wxHORIZONTAL none - + + 5 + + 0 + + 20 + protected + 20 + + + 5 wxEXPAND 1 - - 3 - wxHORIZONTAL - 1 - - 0 + - fgMinValuesSizer - wxFLEX_GROWMODE_SPECIFIED + bSizerOptSettings + wxVERTICAL none - 4 - 0 - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Clearance - - 0 - - - 0 - - 1 - m_ClearanceTitle - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 0 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - 0 - - 1 - m_SetClearance - 1 - - - public - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - By Netclass - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 5 wxEXPAND - 1 - - 0 - protected - 0 + 0 + + 3 + wxHORIZONTAL + 1 + + 0 + + fgMinValuesSizer + wxFLEX_GROWMODE_SPECIFIED + none + 4 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Clearance + + 0 + + + 0 + + 1 + m_ClearanceTitle + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + + 1 + m_SetClearance + 1 + + + public + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + By Netclass + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Min track width + + 0 + + + 0 + + 1 + m_TrackMinWidthTitle + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Enter the minimum acceptable value for a track width + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + + 1 + m_SetTrackMinWidthCtrl + 1 + + + public + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + unit + + 0 + + + 0 + + 1 + m_TrackMinWidthUnit + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Enter the minimum acceptable value for a track width + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + Enter the minimum acceptable diameter for a standard via + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Min via size + + 0 + + + 0 + + 1 + m_ViaMinTitle + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + + 1 + m_SetViaMinSizeCtrl + 1 + + + public + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + Enter the minimum acceptable diameter for a standard via + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + unit + + 0 + + + 0 + + 1 + m_ViaMinUnit + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Min uVia size + + 0 + + + 0 + + 1 + m_MicroViaMinTitle + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Enter the minimum acceptable diameter for a micro via + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + + 1 + m_SetMicroViakMinSizeCtrl + 1 + + + public + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + unit + + 0 + + + 0 + + 1 + m_MicroViaMinUnit + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Enter the minimum acceptable diameter for a micro via + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + - + 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL + wxALL 0 - + 1 1 1 @@ -342,6 +1213,7 @@ 1 0 + 0 1 1 @@ -356,7 +1228,7 @@ 0 0 wxID_ANY - Min track width + Check footprint courtyard overlap 0 @@ -364,7 +1236,7 @@ 0 1 - m_TrackMinWidthTitle + m_cbCourtyardOverlap 1 @@ -377,99 +1249,16 @@ 0 - Enter the minimum acceptable value for a track width - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - 0 - - 1 - m_SetTrackMinWidthCtrl - 1 - - - public - 1 - - Resizable - 1 - - - - 0 wxFILTER_NONE wxDefaultValidator - + @@ -491,18 +1280,14 @@ - - - - - + 5 - wxALL + wxBOTTOM|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -516,6 +1301,7 @@ 1 0 + 0 1 1 @@ -530,7 +1316,7 @@ 0 0 wxID_ANY - unit + Check courtyard missing in footprints 0 @@ -538,7 +1324,7 @@ 0 1 - m_TrackMinWidthUnit + m_cbCourtyardMissing 1 @@ -551,526 +1337,16 @@ 0 - Enter the minimum acceptable value for a track width - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - Enter the minimum acceptable diameter for a standard via - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Min via size - - 0 - - - 0 - - 1 - m_ViaMinTitle - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - 0 - - 1 - m_SetViaMinSizeCtrl - 1 - - - public - 1 - - Resizable - 1 - - - - 0 wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - Enter the minimum acceptable diameter for a standard via - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - unit - - 0 - - - 0 - - 1 - m_ViaMinUnit - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Min uVia size - - 0 - - - 0 - - 1 - m_MicroViaMinTitle - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Enter the minimum acceptable diameter for a micro via - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - 0 - - 1 - m_SetMicroViakMinSizeCtrl - 1 - - - public - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - unit - - 0 - - - 0 - - 1 - m_MicroViaMinUnit - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Enter the minimum acceptable diameter for a micro via - - - - -1 - + @@ -1097,22 +1373,139 @@ - + + + + 5 + + 0 + + 5 + protected + 10 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,92,-1,70,0 + 0 + 0 + wxID_ANY + Create Report File + + 0 + + + 0 + + 1 + m_staticTextRpt + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizerRpt + wxHORIZONTAL + none + 5 - wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT + 0 - - wxID_ANY - Create Report File + + 20 + protected + 20 + + + + 5 + + 1 + + 3 + wxBOTH + 1 + + 0 - ReportFileSizer - wxHORIZONTAL - 1 + fgSizerRpt + wxFLEX_GROWMODE_SPECIFIED none - + 0 + 0 5 - wxALL|wxALIGN_CENTER_VERTICAL + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 0 1 @@ -1200,8 +1593,8 @@ 5 - wxALL|wxEXPAND - 1 + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 0 1 1 @@ -1291,7 +1684,7 @@ 5 - wxALIGN_CENTER_VERTICAL + wxALIGN_CENTER_VERTICAL|wxRIGHT 0 1 @@ -1383,11 +1776,11 @@ - + 5 wxEXPAND 1 - + bSizerMessages wxVERTICAL @@ -1568,11 +1961,11 @@ - + 5 wxALIGN_CENTER_VERTICAL 0 - + bSizer11 wxVERTICAL diff --git a/pcbnew/dialogs/dialog_drc_base.h b/pcbnew/dialogs/dialog_drc_base.h index 365f5f1e95..05f97874ef 100644 --- a/pcbnew/dialogs/dialog_drc_base.h +++ b/pcbnew/dialogs/dialog_drc_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Feb 16 2016) +// C++ code generated with wxFormBuilder (version May 6 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -25,7 +25,6 @@ class DRCLISTBOX; #include #include #include -#include #include #include #include @@ -33,6 +32,7 @@ class DRCLISTBOX; #include #include #include +#include #include /////////////////////////////////////////////////////////////////////////// @@ -55,6 +55,7 @@ class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM wxPanel* m_panelUnconnectedBox; protected: + wxStaticText* m_staticTextOptions; wxStaticText* m_ClearanceTitle; wxStaticText* m_TrackMinWidthTitle; wxStaticText* m_TrackMinWidthUnit; @@ -62,6 +63,9 @@ class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM wxStaticText* m_ViaMinUnit; wxStaticText* m_MicroViaMinTitle; wxStaticText* m_MicroViaMinUnit; + wxCheckBox* m_cbCourtyardOverlap; + wxCheckBox* m_cbCourtyardMissing; + wxStaticText* m_staticTextRpt; wxCheckBox* m_CreateRptCtrl; wxTextCtrl* m_RptFilenameCtrl; wxButton* m_BrowseButton; @@ -109,7 +113,7 @@ class DIALOG_DRC_CONTROL_BASE : public DIALOG_SHIM DRCLISTBOX* m_ClearanceListBox; DRCLISTBOX* m_UnconnectedListBox; - DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("DRC Control"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 733,438 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_DRC_CONTROL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("DRC Control"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 679,518 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_DRC_CONTROL_BASE(); }; diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index c74dc88378..1b770a8675 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -2,9 +2,9 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2004-2017 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2014 Dick Hollenbeck, dick@softplc.com - * Copyright (C) 2016 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -122,6 +122,8 @@ DRC::DRC( PCB_EDIT_FRAME* aPcbWindow ) m_doUnconnectedTest = true; // enable unconnected tests m_doZonesTest = true; // enable zone to items clearance tests m_doKeepoutTest = true; // enable keepout areas to items clearance tests + m_doFootprintOverlapping = true; // enable courtyards areas overlap tests + m_doNoCourtyardDefined = true; // enable missing courtyard in footprint warning m_abortDRC = false; m_drcInProgress = false; @@ -298,6 +300,18 @@ void DRC::RunTests( wxTextCtrl* aMessages ) testTexts(); + // find overlaping courtyard ares. + if( m_doFootprintOverlapping || m_doNoCourtyardDefined ) + { + if( aMessages ) + { + aMessages->AppendText( _( "Courtyard areas...\n" ) ); + aMessages->Refresh(); + } + + doFootprintOverlappingDrc(); + } + // update the m_drcDialog listboxes updatePointers(); @@ -968,3 +982,70 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li return true; } + + +bool DRC::doFootprintOverlappingDrc() +{ + // Detects missing footprint courtyards, and for others, courtyard overlap. + wxString msg; + bool success = true; + + // Update courtyard polygons, and test for missing courtyard definition: + for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() ) + { + footprint->BuildPolyCourtyard(); + + if( footprint->GetPolyCourtyard().OutlineCount() == 0 && m_doNoCourtyardDefined ) + { + msg.Printf( _( "footprint '%s' has no courtyard defined" ), + footprint->GetReference().GetData() ); + m_currentMarker = fillMarker( footprint->GetPosition(), + DRCE_MISSING_COURTYARD_IN_FOOTPRINT, + msg, m_currentMarker ); + addMarkerToPcb( m_currentMarker ); + m_currentMarker = nullptr; + success = false; + } + } + + if( !m_doFootprintOverlapping ) + return success; + + // Now test for overlapping: + for( MODULE* footprint = m_pcb->m_Modules; footprint; footprint = footprint->Next() ) + { + if( footprint->GetPolyCourtyard().OutlineCount() == 0 ) + continue; // No courtyard defined + + for( MODULE* candidate = footprint->Next(); candidate; candidate = candidate->Next() ) + { + if( candidate->GetPolyCourtyard().OutlineCount() == 0 ) + continue; // No courtyard defined + + SHAPE_POLY_SET courtyard; + courtyard.Append( footprint->GetPolyCourtyard() ); + + // Build the common area between footprint and the candidate: + courtyard.BooleanIntersection( candidate->GetPolyCourtyard(), SHAPE_POLY_SET::PM_FAST ); + + // If no overlap, courtyard is empty (no common area). + // Therefore if a common polygon exists, this is a DRC error + if( courtyard.OutlineCount() ) + { + //Overlap between footprint and candidate + msg.Printf( _( "footprints '%s' and '%s' overlap" ), + footprint->GetReference().GetData(), + candidate->GetReference().GetData() ); + VECTOR2I& pos = courtyard.Vertex( 0, 0 ); + wxPoint loc( pos.x, pos.y ); + m_currentMarker = fillMarker( loc, DRCE_OVERLAPPING_FOOTPRINTS, msg, m_currentMarker ); + addMarkerToPcb( m_currentMarker ); + m_currentMarker = nullptr; + success = false; + } + } + } + + return success; +} + diff --git a/pcbnew/drc_marker_functions.cpp b/pcbnew/drc_marker_functions.cpp index 56423612fa..0d5719c60b 100644 --- a/pcbnew/drc_marker_functions.cpp +++ b/pcbnew/drc_marker_functions.cpp @@ -6,8 +6,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2010 Dick Hollenbeck, dick@softplc.com - * Copyright (C) 2004-2010 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr - * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2004-2017 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -224,3 +224,16 @@ MARKER_PCB* DRC::fillMarker( int aErrorCode, const wxString& aMessage, MARKER_PC return fillMe; } + +MARKER_PCB* DRC::fillMarker( const wxPoint& aPos, int aErrorCode, const wxString& aMessage, MARKER_PCB* fillMe ) +{ + wxPoint posA = aPos; + + if( fillMe ) + fillMe->SetData( aErrorCode, posA, aMessage, posA ); + else + fillMe = new MARKER_PCB( aErrorCode, posA, aMessage, posA ); + + return fillMe; +} + diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h index 1c33bcc4c2..f00e532d9c 100644 --- a/pcbnew/drc_stuff.h +++ b/pcbnew/drc_stuff.h @@ -6,7 +6,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2007-2016 Dick Hollenbeck, dick@softplc.com - * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -80,6 +80,8 @@ #define DRCE_VIA_INSIDE_TEXT 41 ///< Via in inside a text area #define DRCE_TRACK_INSIDE_TEXT 42 ///< Track in inside a text area #define DRCE_PAD_INSIDE_TEXT 43 ///< Pad in inside a text area +#define DRCE_OVERLAPPING_FOOTPRINTS 44 ///< footprint courtyards overlap +#define DRCE_MISSING_COURTYARD_IN_FOOTPRINT 45 ///< footprint has no courtyard defined class EDA_DRAW_PANEL; @@ -164,6 +166,8 @@ private: bool m_doZonesTest; bool m_doKeepoutTest; bool m_doCreateRptFile; + bool m_doFootprintOverlapping; + bool m_doNoCourtyardDefined; wxString m_rptFilename; @@ -230,6 +234,9 @@ private: MARKER_PCB* fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* fillMe ); + MARKER_PCB* fillMarker( const wxPoint& aPos, int aErrorCode, + const wxString& aMessage, MARKER_PCB* fillMe ); + /** * Function fillMarker * optionally creates a marker and fills it in with information, @@ -341,6 +348,13 @@ private: */ bool doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ); + /** + * Function doFootprintOverlappingDrc + * tests for footprint courtyard overlaps + * @return bool - false if DRC error or true if OK + */ + bool doFootprintOverlappingDrc(); + //--------------------------------------------------- /** @@ -476,19 +490,24 @@ public: * @param aUnconnectedTest Tells whether to list unconnected pads. * @param aZonesTest Tells whether to test zones. * @param aKeepoutTest Tells whether to test keepout areas. + * @param aCourtyardTest Tells whether to test footprint courtyard overlap. + * @param aCourtyardMissingTest Tells whether to test missing courtyard definition in footprint. * @param aReportName A string telling the disk file report name entered. * @param aSaveReport A boolean telling whether to generate disk file report. */ void SetSettings( bool aPad2PadTest, bool aUnconnectedTest, bool aZonesTest, bool aKeepoutTest, + bool aCourtyardTest, bool aCourtyardMissingTest, const wxString& aReportName, bool aSaveReport ) { - m_doPad2PadTest = aPad2PadTest; - m_doUnconnectedTest = aUnconnectedTest; - m_doZonesTest = aZonesTest; - m_doKeepoutTest = aKeepoutTest; - m_rptFilename = aReportName; - m_doCreateRptFile = aSaveReport; + m_doPad2PadTest = aPad2PadTest; + m_doUnconnectedTest = aUnconnectedTest; + m_doZonesTest = aZonesTest; + m_doKeepoutTest = aKeepoutTest; + m_rptFilename = aReportName; + m_doCreateRptFile = aSaveReport; + m_doFootprintOverlapping = aCourtyardTest; + m_doNoCourtyardDefined = aCourtyardMissingTest; }