diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 38754c3f2c..f20df851ce 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -211,10 +211,15 @@ set( PCBNEW_MICROWAVE_SRCS microwave/microwave_inductor.cpp ) +set( PCBNEW_DRC_SRCS + drc/drc_marker_factory.cpp + ) + set( PCBNEW_CLASS_SRCS ${PCBNEW_DIALOGS} ${PCBNEW_EXPORTERS} ${PCBNEW_IMPORT_GFX} + ${PCBNEW_DRC_SRCS} autorouter/rect_placement/rect_placement.cpp autorouter/spread_footprints.cpp @@ -238,7 +243,6 @@ set( PCBNEW_CLASS_SRCS dragsegm.cpp drc.cpp drc_clearance_test_functions.cpp - drc_marker_functions.cpp edgemod.cpp edit.cpp edit_pcb_text.cpp diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 31c696e7a7..5c4a400b4b 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -155,6 +155,8 @@ DRC::DRC( PCB_EDIT_FRAME* aPcbWindow ) m_ycliplo = 0; m_xcliphi = 0; m_ycliphi = 0; + + m_markerFactory.SetUnitsProvider( [=]() { return aPcbWindow->GetUserUnits(); } ); } @@ -283,7 +285,8 @@ int DRC::TestZoneToZoneOutline( ZONE_CONTAINER* aZone, bool aCreateMarkers ) if( smoothed_polys[ia2].Contains( currentVertex ) ) { if( aCreateMarkers ) - commit.Add( newMarker( pt, zoneRef, zoneToTest, DRCE_ZONES_INTERSECT ) ); + commit.Add( m_markerFactory.NewMarker( + pt, zoneRef, zoneToTest, DRCE_ZONES_INTERSECT ) ); nerrors++; } @@ -298,7 +301,8 @@ int DRC::TestZoneToZoneOutline( ZONE_CONTAINER* aZone, bool aCreateMarkers ) if( smoothed_polys[ia].Contains( currentVertex ) ) { if( aCreateMarkers ) - commit.Add( newMarker( pt, zoneToTest, zoneRef, DRCE_ZONES_INTERSECT ) ); + commit.Add( m_markerFactory.NewMarker( + pt, zoneToTest, zoneRef, DRCE_ZONES_INTERSECT ) ); nerrors++; } @@ -346,7 +350,8 @@ int DRC::TestZoneToZoneOutline( ZONE_CONTAINER* aZone, bool aCreateMarkers ) for( wxPoint pt : conflictPoints ) { if( aCreateMarkers ) - commit.Add( newMarker( pt, zoneRef, zoneToTest, DRCE_ZONES_TOO_CLOSE ) ); + commit.Add( m_markerFactory.NewMarker( + pt, zoneRef, zoneToTest, DRCE_ZONES_TOO_CLOSE ) ); nerrors++; } @@ -598,7 +603,7 @@ bool DRC::doNetClass( const NETCLASSPTR& nc, wxString& msg ) FmtVal( g.m_TrackMinWidth ) ); - addMarkerToPcb( newMarker( DRCE_NETCLASS_TRACKWIDTH, msg ) ); + addMarkerToPcb( m_markerFactory.NewMarker( DRCE_NETCLASS_TRACKWIDTH, msg ) ); ret = false; } @@ -610,7 +615,7 @@ bool DRC::doNetClass( const NETCLASSPTR& nc, wxString& msg ) FmtVal( g.m_ViasMinSize ) ); - addMarkerToPcb( newMarker( DRCE_NETCLASS_VIASIZE, msg ) ); + addMarkerToPcb( m_markerFactory.NewMarker( DRCE_NETCLASS_VIASIZE, msg ) ); ret = false; } @@ -622,7 +627,7 @@ bool DRC::doNetClass( const NETCLASSPTR& nc, wxString& msg ) FmtVal( g.m_ViasMinDrill ) ); - addMarkerToPcb( newMarker( DRCE_NETCLASS_VIADRILLSIZE, msg ) ); + addMarkerToPcb( m_markerFactory.NewMarker( DRCE_NETCLASS_VIADRILLSIZE, msg ) ); ret = false; } @@ -633,7 +638,7 @@ bool DRC::doNetClass( const NETCLASSPTR& nc, wxString& msg ) FmtVal( nc->GetuViaDiameter() ), FmtVal( g.m_MicroViasMinSize ) ); - addMarkerToPcb( newMarker( DRCE_NETCLASS_uVIASIZE, msg ) ); + addMarkerToPcb( m_markerFactory.NewMarker( DRCE_NETCLASS_uVIASIZE, msg ) ); ret = false; } @@ -644,7 +649,7 @@ bool DRC::doNetClass( const NETCLASSPTR& nc, wxString& msg ) FmtVal( nc->GetuViaDrill() ), FmtVal( g.m_MicroViasMinDrill ) ); - addMarkerToPcb( newMarker( DRCE_NETCLASS_uVIADRILLSIZE, msg ) ); + addMarkerToPcb( m_markerFactory.NewMarker( DRCE_NETCLASS_uVIADRILLSIZE, msg ) ); ret = false; } @@ -905,7 +910,8 @@ void DRC::testZones() if( ( netcode < 0 ) || pads_in_net == 0 ) { wxPoint markerPos = zone->GetPosition(); - addMarkerToPcb( newMarker( markerPos, zone, DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE ) ); + addMarkerToPcb( m_markerFactory.NewMarker( + markerPos, zone, DRCE_SUSPICIOUS_NET_FOR_ZONE_OUTLINE ) ); } } @@ -940,7 +946,8 @@ void DRC::testKeepoutAreas() SEG trackSeg( segm->GetStart(), segm->GetEnd() ); if( area->Outline()->Distance( trackSeg, segm->GetWidth() ) == 0 ) - addMarkerToPcb( newMarker( segm, area, DRCE_TRACK_INSIDE_KEEPOUT ) ); + addMarkerToPcb( + m_markerFactory.NewMarker( segm, area, DRCE_TRACK_INSIDE_KEEPOUT ) ); } else if( segm->Type() == PCB_VIA_T ) { @@ -953,7 +960,8 @@ void DRC::testKeepoutAreas() continue; if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 ) - addMarkerToPcb( newMarker( segm, area, DRCE_VIA_INSIDE_KEEPOUT ) ); + addMarkerToPcb( + m_markerFactory.NewMarker( segm, area, DRCE_VIA_INSIDE_KEEPOUT ) ); } } // Test pads: TODO @@ -1073,9 +1081,11 @@ void DRC::testCopperDrawItem( DRAWSEGMENT* aItem ) if( trackAsSeg.Distance( itemSeg ) < minDist ) { if( track->Type() == PCB_VIA_T ) - addMarkerToPcb( newMarker( track, aItem, itemSeg, DRCE_VIA_NEAR_COPPER ) ); + addMarkerToPcb( m_markerFactory.NewMarker( + track, aItem, itemSeg, DRCE_VIA_NEAR_COPPER ) ); else - addMarkerToPcb( newMarker( track, aItem, itemSeg, DRCE_TRACK_NEAR_COPPER ) ); + addMarkerToPcb( m_markerFactory.NewMarker( + track, aItem, itemSeg, DRCE_TRACK_NEAR_COPPER ) ); break; } } @@ -1099,7 +1109,7 @@ void DRC::testCopperDrawItem( DRAWSEGMENT* aItem ) { if( padOutline.Distance( itemSeg, itemWidth ) == 0 ) { - addMarkerToPcb( newMarker( pad, aItem, DRCE_PAD_NEAR_COPPER ) ); + addMarkerToPcb( m_markerFactory.NewMarker( pad, aItem, DRCE_PAD_NEAR_COPPER ) ); break; } } @@ -1139,9 +1149,11 @@ void DRC::testCopperTextItem( BOARD_ITEM* aTextItem ) if( trackAsSeg.Distance( textSeg ) < minDist ) { if( track->Type() == PCB_VIA_T ) - addMarkerToPcb( newMarker( track, aTextItem, textSeg, DRCE_VIA_NEAR_COPPER ) ); + addMarkerToPcb( m_markerFactory.NewMarker( + track, aTextItem, textSeg, DRCE_VIA_NEAR_COPPER ) ); else - addMarkerToPcb( newMarker( track, aTextItem, textSeg, DRCE_TRACK_NEAR_COPPER ) ); + addMarkerToPcb( m_markerFactory.NewMarker( + track, aTextItem, textSeg, DRCE_TRACK_NEAR_COPPER ) ); break; } } @@ -1167,7 +1179,7 @@ void DRC::testCopperTextItem( BOARD_ITEM* aTextItem ) if( padOutline.Distance( textSeg, textWidth ) == 0 ) { - addMarkerToPcb( newMarker( pad, aTextItem, DRCE_PAD_NEAR_COPPER ) ); + addMarkerToPcb( m_markerFactory.NewMarker( pad, aTextItem, DRCE_PAD_NEAR_COPPER ) ); break; } } @@ -1180,7 +1192,7 @@ void DRC::testOutline() wxPoint error_loc( m_pcb->GetBoardEdgesBoundingBox().GetPosition() ); if( !m_pcb->GetBoardPolygonOutlines( m_board_outlines, nullptr, &error_loc ) ) { - addMarkerToPcb( newMarker( error_loc, m_pcb, DRCE_INVALID_OUTLINE ) ); + addMarkerToPcb( m_markerFactory.NewMarker( error_loc, m_pcb, DRCE_INVALID_OUTLINE ) ); return; } } @@ -1195,9 +1207,9 @@ void DRC::testDisabledLayers() // Perform the test only for copper layers disabledLayers &= LSET::AllCuMask(); - auto createMarker = [&]( BOARD_ITEM* aItem ) - { - addMarkerToPcb( newMarker( aItem->GetPosition(), aItem, DRCE_DISABLED_LAYER_ITEM ) ); + auto createMarker = [&]( BOARD_ITEM* aItem ) { + addMarkerToPcb( m_markerFactory.NewMarker( + aItem->GetPosition(), aItem, DRCE_DISABLED_LAYER_ITEM ) ); }; for( auto track : board->Tracks() ) @@ -1244,7 +1256,8 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) if( area->Outline()->Distance( SEG( aRefSeg->GetStart(), aRefSeg->GetEnd() ), aRefSeg->GetWidth() ) == 0 ) { - m_currentMarker = newMarker( aRefSeg, area, DRCE_TRACK_INSIDE_KEEPOUT ); + m_currentMarker = + m_markerFactory.NewMarker( aRefSeg, area, DRCE_TRACK_INSIDE_KEEPOUT ); return false; } } @@ -1260,7 +1273,8 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 ) { - m_currentMarker = newMarker( aRefSeg, area, DRCE_VIA_INSIDE_KEEPOUT ); + m_currentMarker = + m_markerFactory.NewMarker( aRefSeg, area, DRCE_VIA_INSIDE_KEEPOUT ); return false; } } @@ -1342,7 +1356,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li if( !checkClearancePadToPad( aRefPad, &dummypad ) ) { // here we have a drc error on pad! - m_currentMarker = newMarker( pad, aRefPad, DRCE_HOLE_NEAR_PAD ); + m_currentMarker = m_markerFactory.NewMarker( pad, aRefPad, DRCE_HOLE_NEAR_PAD ); return false; } } @@ -1358,7 +1372,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li if( !checkClearancePadToPad( pad, &dummypad ) ) { // here we have a drc error on aRefPad! - m_currentMarker = newMarker( aRefPad, pad, DRCE_HOLE_NEAR_PAD ); + m_currentMarker = m_markerFactory.NewMarker( aRefPad, pad, DRCE_HOLE_NEAR_PAD ); return false; } } @@ -1393,7 +1407,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li if( !checkClearancePadToPad( aRefPad, pad ) ) { // here we have a drc error! - m_currentMarker = newMarker( aRefPad, pad, DRCE_PAD_NEAR_PAD1 ); + m_currentMarker = m_markerFactory.NewMarker( aRefPad, pad, DRCE_PAD_NEAR_PAD1 ); return false; } } @@ -1417,7 +1431,8 @@ bool DRC::doFootprintOverlappingDrc() if( !is_ok && m_pcb->GetDesignSettings().m_ProhibitOverlappingCourtyards ) { - addMarkerToPcb( newMarker( pos, footprint, DRCE_MALFORMED_COURTYARD_IN_FOOTPRINT ) ); + addMarkerToPcb( m_markerFactory.NewMarker( + pos, footprint, DRCE_MALFORMED_COURTYARD_IN_FOOTPRINT ) ); success = false; } @@ -1428,7 +1443,8 @@ bool DRC::doFootprintOverlappingDrc() footprint->GetPolyCourtyardBack().OutlineCount() == 0 && is_ok ) { - addMarkerToPcb( newMarker( pos, footprint, DRCE_MISSING_COURTYARD_IN_FOOTPRINT ) ); + addMarkerToPcb( m_markerFactory.NewMarker( + pos, footprint, DRCE_MISSING_COURTYARD_IN_FOOTPRINT ) ); success = false; } } @@ -1462,8 +1478,8 @@ bool DRC::doFootprintOverlappingDrc() { //Overlap between footprint and candidate VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 ); - addMarkerToPcb( newMarker( wxPoint( pos.x, pos.y ), footprint, candidate, - DRCE_OVERLAPPING_FOOTPRINTS ) ); + addMarkerToPcb( m_markerFactory.NewMarker( wxPoint( pos.x, pos.y ), footprint, + candidate, DRCE_OVERLAPPING_FOOTPRINTS ) ); success = false; } } @@ -1493,8 +1509,8 @@ bool DRC::doFootprintOverlappingDrc() { //Overlap between footprint and candidate VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 ); - addMarkerToPcb( newMarker( wxPoint( pos.x, pos.y ), footprint, candidate, - DRCE_OVERLAPPING_FOOTPRINTS ) ); + addMarkerToPcb( m_markerFactory.NewMarker( wxPoint( pos.x, pos.y ), footprint, + candidate, DRCE_OVERLAPPING_FOOTPRINTS ) ); success = false; } } diff --git a/pcbnew/drc.h b/pcbnew/drc.h index b20600c9c4..012d135e5c 100644 --- a/pcbnew/drc.h +++ b/pcbnew/drc.h @@ -34,6 +34,8 @@ #include #include +#include + #define OK_DRC 0 #define BAD_DRC 1 @@ -225,6 +227,7 @@ private: BOARD* m_pcb; SHAPE_POLY_SET m_board_outlines; ///< The board outline including cutouts DIALOG_DRC_CONTROL* m_drcDialog; + DRC_MARKER_FACTORY m_markerFactory; ///< Class that generates markers DRC_LIST m_unconnected; ///< list of unconnected pads, as DRC_ITEMs @@ -234,42 +237,6 @@ private: */ void updatePointers(); - - /** - * Function newMarker - * Creates a marker on a track, via or pad. - * - * @param aTrack/aPad The reference item. - * @param aConflitItem Another item on the board which is in conflict with the - * reference item. - * @param aErrorCode An ID for the particular type of error that is being reported. - */ - MARKER_PCB* newMarker( TRACK* aTrack, BOARD_ITEM* aConflitItem, const SEG& aConflictSeg, - int aErrorCode ); - - MARKER_PCB* newMarker( TRACK* aTrack, ZONE_CONTAINER* aConflictZone, int aErrorCode ); - - MARKER_PCB* newMarker( D_PAD* aPad, BOARD_ITEM* aConflictItem, int aErrorCode ); - - /** - * Function newMarker - * Creates a marker at a given location. - * - * @param aItem The reference item. - * @param aPos Usually the position of the item, but could be more specific for a zone. - * @param aErrorCode An ID for the particular type of error that is being reported. - */ - MARKER_PCB* newMarker( const wxPoint& aPos, BOARD_ITEM* aItem, int aErrorCode ); - - MARKER_PCB* newMarker( const wxPoint& aPos, BOARD_ITEM* aItem, BOARD_ITEM* bItem, - int aErrorCode ); - - /** - * Create a MARKER which will report on a generic problem with the board which is - * not geographically locatable. - */ - MARKER_PCB* newMarker( int aErrorCode, const wxString& aMessage ); - /** * Adds a DRC marker to the PCB through the COMMIT mechanism. */ diff --git a/pcbnew/drc_marker_functions.cpp b/pcbnew/drc/drc_marker_factory.cpp similarity index 63% rename from pcbnew/drc_marker_functions.cpp rename to pcbnew/drc/drc_marker_factory.cpp index 2cb9b2e92f..0ffbf2f203 100644 --- a/pcbnew/drc_marker_functions.cpp +++ b/pcbnew/drc/drc_marker_factory.cpp @@ -1,7 +1,3 @@ -/** - * @file drc_marker_functions.cpp - */ - /* * This program source code file is part of KiCad, a free EDA CAD application. * @@ -27,32 +23,48 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "drc_marker_factory.h" -/* Methods of class DRC to initialize drc markers with messages - * according to items and error code -*/ - -#include -#include -#include #include -#include -#include -#include -#include -#include -#include +#include +#include #include +#include #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include const int EPSILON = Mils2iu( 5 ); -MARKER_PCB* DRC::newMarker( TRACK* aTrack, ZONE_CONTAINER* aConflictZone, int aErrorCode ) +DRC_MARKER_FACTORY::DRC_MARKER_FACTORY() +{ + SetUnits( EDA_UNITS_T::MILLIMETRES ); +} + + +void DRC_MARKER_FACTORY::SetUnitsProvider( UNITS_PROVIDER aUnitsProvider ) +{ + m_units_provider = aUnitsProvider; +} + + +void DRC_MARKER_FACTORY::SetUnits( EDA_UNITS_T aUnits ) +{ + m_units_provider = [=]() { return aUnits; }; +} + + +MARKER_PCB* DRC_MARKER_FACTORY::NewMarker( + TRACK* aTrack, ZONE_CONTAINER* aConflictZone, int aErrorCode ) const { SHAPE_POLY_SET* conflictOutline; @@ -84,16 +96,15 @@ MARKER_PCB* DRC::newMarker( TRACK* aTrack, ZONE_CONTAINER* aConflictZone, int aE markerPos = pt1; } - return new MARKER_PCB( m_pcbEditorFrame->GetUserUnits(), aErrorCode, markerPos, - aTrack, aTrack->GetPosition(), - aConflictZone, aConflictZone->GetPosition() ); + return new MARKER_PCB( getCurrentUnits(), aErrorCode, markerPos, aTrack, aTrack->GetPosition(), + aConflictZone, aConflictZone->GetPosition() ); } -MARKER_PCB* DRC::newMarker( TRACK* aTrack, BOARD_ITEM* aConflitItem, const SEG& aConflictSeg, - int aErrorCode ) +MARKER_PCB* DRC_MARKER_FACTORY::NewMarker( + TRACK* aTrack, BOARD_ITEM* aConflitItem, const SEG& aConflictSeg, int aErrorCode ) const { - wxPoint markerPos; + wxPoint markerPos; wxPoint pt1 = aTrack->GetPosition(); wxPoint pt2 = aTrack->GetEnd(); @@ -109,36 +120,36 @@ MARKER_PCB* DRC::newMarker( TRACK* aTrack, BOARD_ITEM* aConflitItem, const SEG& // Once we're within EPSILON pt1 and pt2 are "equivalent" markerPos = pt1; - return new MARKER_PCB( m_pcbEditorFrame->GetUserUnits(), aErrorCode, markerPos, - aTrack, aTrack->GetPosition(), - aConflitItem, aConflitItem->GetPosition() ); + return new MARKER_PCB( getCurrentUnits(), aErrorCode, markerPos, aTrack, aTrack->GetPosition(), + aConflitItem, aConflitItem->GetPosition() ); } -MARKER_PCB* DRC::newMarker( D_PAD* aPad, BOARD_ITEM* aConflictItem, int aErrorCode ) +MARKER_PCB* DRC_MARKER_FACTORY::NewMarker( + D_PAD* aPad, BOARD_ITEM* aConflictItem, int aErrorCode ) const { - return new MARKER_PCB( m_pcbEditorFrame->GetUserUnits(), aErrorCode, aPad->GetPosition(), - aPad, aPad->GetPosition(), - aConflictItem, aConflictItem->GetPosition() ); + return new MARKER_PCB( getCurrentUnits(), aErrorCode, aPad->GetPosition(), aPad, + aPad->GetPosition(), aConflictItem, aConflictItem->GetPosition() ); } -MARKER_PCB* DRC::newMarker(const wxPoint &aPos, BOARD_ITEM *aItem, int aErrorCode ) +MARKER_PCB* DRC_MARKER_FACTORY::NewMarker( + const wxPoint& aPos, BOARD_ITEM* aItem, int aErrorCode ) const { - return new MARKER_PCB( m_pcbEditorFrame->GetUserUnits(), aErrorCode, aPos, - aItem, aItem->GetPosition(), nullptr, wxPoint() ); + return new MARKER_PCB( + getCurrentUnits(), aErrorCode, aPos, aItem, aItem->GetPosition(), nullptr, wxPoint() ); } -MARKER_PCB* DRC::newMarker( const wxPoint &aPos, BOARD_ITEM* aItem, BOARD_ITEM* bItem, - int aErrorCode ) +MARKER_PCB* DRC_MARKER_FACTORY::NewMarker( + const wxPoint& aPos, BOARD_ITEM* aItem, BOARD_ITEM* bItem, int aErrorCode ) const { - return new MARKER_PCB( m_pcbEditorFrame->GetUserUnits(), aErrorCode, aPos, - aItem, aItem->GetPosition(), bItem, bItem->GetPosition() ); + return new MARKER_PCB( getCurrentUnits(), aErrorCode, aPos, aItem, aItem->GetPosition(), bItem, + bItem->GetPosition() ); } -MARKER_PCB* DRC::newMarker( int aErrorCode, const wxString& aMessage ) +MARKER_PCB* DRC_MARKER_FACTORY::NewMarker( int aErrorCode, const wxString& aMessage ) const { MARKER_PCB* marker = new MARKER_PCB( aErrorCode, wxPoint(), aMessage, wxPoint() ); @@ -146,5 +157,3 @@ MARKER_PCB* DRC::newMarker( int aErrorCode, const wxString& aMessage ) return marker; } - - diff --git a/pcbnew/drc/drc_marker_factory.h b/pcbnew/drc/drc_marker_factory.h new file mode 100644 index 0000000000..7d18e7c707 --- /dev/null +++ b/pcbnew/drc/drc_marker_factory.h @@ -0,0 +1,104 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2018 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#ifndef DRC_DRC_MARKER_FACTORY__H +#define DRC_DRC_MARKER_FACTORY__H + + +#include +#include // for EDA_UNITS_T + + +class ZONE_CONTAINER; +class TRACK; +class D_PAD; +class SEG; + +/** + * Class that constructs DRC markers of various kinds + * with messages according to items and error code + */ +class DRC_MARKER_FACTORY +{ +public: + using UNITS_PROVIDER = std::function; + + DRC_MARKER_FACTORY(); + + /** + * Set the provider for the units (this will be called for each new + * marker constructed) + * @param aUnitsProvider a callable that returns the current units to use + */ + void SetUnitsProvider( UNITS_PROVIDER aUnitsProvider ); + + /** + * Set the units provider to a function returning a constant value. + * This is a shorthand for #SetUnitProvider. + */ + void SetUnits( EDA_UNITS_T aUnits ); + + /** + * Creates a marker on a track, via or pad. + * + * @param aTrack/aPad The reference item. + * @param aConflitItem Another item on the board which is in conflict with the + * reference item. + * @param aErrorCode An ID for the particular type of error that is being reported. + */ + MARKER_PCB* NewMarker( TRACK* aTrack, BOARD_ITEM* aConflitItem, const SEG& aConflictSeg, + int aErrorCode ) const; + + MARKER_PCB* NewMarker( TRACK* aTrack, ZONE_CONTAINER* aConflictZone, int aErrorCode ) const; + + MARKER_PCB* NewMarker( D_PAD* aPad, BOARD_ITEM* aConflictItem, int aErrorCode ) const; + + /** + * Creates a marker at a given location. + * + * @param aItem The reference item. + * @param aPos Usually the position of the item, but could be more specific for a zone. + * @param aErrorCode An ID for the particular type of error that is being reported. + */ + MARKER_PCB* NewMarker( const wxPoint& aPos, BOARD_ITEM* aItem, int aErrorCode ) const; + + MARKER_PCB* NewMarker( + const wxPoint& aPos, BOARD_ITEM* aItem, BOARD_ITEM* bItem, int aErrorCode ) const; + + /** + * Create a MARKER which will report on a generic problem with the board which is + * not geographically locatable. + */ + MARKER_PCB* NewMarker( int aErrorCode, const wxString& aMessage ) const; + +private: + EDA_UNITS_T getCurrentUnits() const + { + return m_units_provider(); + } + + UNITS_PROVIDER m_units_provider; +}; + +#endif // DRC_DRC_MARKER_FACTORY__H \ No newline at end of file diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp index a3920204a2..d6273ecbd4 100644 --- a/pcbnew/drc_clearance_test_functions.cpp +++ b/pcbnew/drc_clearance_test_functions.cpp @@ -211,7 +211,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) { if( refvia->GetWidth() < dsnSettings.m_MicroViasMinSize ) { - markers.push_back( newMarker( refviaPos, refvia, DRCE_TOO_SMALL_MICROVIA ) ); + markers.push_back( + m_markerFactory.NewMarker( refviaPos, refvia, DRCE_TOO_SMALL_MICROVIA ) ); if( !handleNewMarker() ) return false; @@ -219,7 +220,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( refvia->GetDrillValue() < dsnSettings.m_MicroViasMinDrill ) { - markers.push_back( newMarker( refviaPos, refvia, DRCE_TOO_SMALL_MICROVIA_DRILL ) ); + markers.push_back( m_markerFactory.NewMarker( + refviaPos, refvia, DRCE_TOO_SMALL_MICROVIA_DRILL ) ); if( !handleNewMarker() ) return false; @@ -229,7 +231,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) { if( refvia->GetWidth() < dsnSettings.m_ViasMinSize ) { - markers.push_back( newMarker( refviaPos, refvia, DRCE_TOO_SMALL_VIA ) ); + markers.push_back( + m_markerFactory.NewMarker( refviaPos, refvia, DRCE_TOO_SMALL_VIA ) ); if( !handleNewMarker() ) return false; @@ -237,7 +240,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( refvia->GetDrillValue() < dsnSettings.m_ViasMinDrill ) { - markers.push_back( newMarker( refviaPos, refvia, DRCE_TOO_SMALL_VIA_DRILL ) ); + markers.push_back( + m_markerFactory.NewMarker( refviaPos, refvia, DRCE_TOO_SMALL_VIA_DRILL ) ); if( !handleNewMarker() ) return false; @@ -249,7 +253,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // and a default via hole can be bigger than some vias sizes if( refvia->GetDrillValue() > refvia->GetWidth() ) { - markers.push_back( newMarker( refviaPos, refvia, DRCE_VIA_HOLE_BIGGER ) ); + markers.push_back( + m_markerFactory.NewMarker( refviaPos, refvia, DRCE_VIA_HOLE_BIGGER ) ); if( !handleNewMarker() ) return false; @@ -258,7 +263,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // test if the type of via is allowed due to design rules if( refvia->GetViaType() == VIA_MICROVIA && !dsnSettings.m_MicroViasAllowed ) { - markers.push_back( newMarker( refviaPos, refvia, DRCE_MICRO_VIA_NOT_ALLOWED ) ); + markers.push_back( + m_markerFactory.NewMarker( refviaPos, refvia, DRCE_MICRO_VIA_NOT_ALLOWED ) ); if( !handleNewMarker() ) return false; } @@ -266,7 +272,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // test if the type of via is allowed due to design rules if( refvia->GetViaType() == VIA_BLIND_BURIED && !dsnSettings.m_BlindBuriedViaAllowed ) { - markers.push_back( newMarker( refviaPos, refvia, DRCE_BURIED_VIA_NOT_ALLOWED ) ); + markers.push_back( + m_markerFactory.NewMarker( refviaPos, refvia, DRCE_BURIED_VIA_NOT_ALLOWED ) ); if( !handleNewMarker() ) return false; @@ -292,7 +299,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( err ) { - markers.push_back( newMarker( refviaPos, refvia, DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR ) ); + markers.push_back( m_markerFactory.NewMarker( + refviaPos, refvia, DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR ) ); if( !handleNewMarker() ) return false; @@ -306,7 +314,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) { wxPoint refsegMiddle = ( aRefSeg->GetStart() + aRefSeg->GetEnd() ) / 2; - markers.push_back( newMarker( refsegMiddle, aRefSeg, DRCE_TOO_SMALL_TRACK_WIDTH ) ); + markers.push_back( m_markerFactory.NewMarker( + refsegMiddle, aRefSeg, DRCE_TOO_SMALL_TRACK_WIDTH ) ); if( !handleNewMarker() ) return false; @@ -381,8 +390,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkClearanceSegmToPad( &dummypad, aRefSeg->GetWidth(), netclass->GetClearance() ) ) { - markers.push_back( newMarker( aRefSeg, pad, padSeg, - DRCE_TRACK_NEAR_THROUGH_HOLE ) ); + markers.push_back( m_markerFactory.NewMarker( + aRefSeg, pad, padSeg, DRCE_TRACK_NEAR_THROUGH_HOLE ) ); if( !handleNewMarker() ) return false; @@ -403,7 +412,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkClearanceSegmToPad( pad, aRefSeg->GetWidth(), aRefSeg->GetClearance( pad ) ) ) { - markers.push_back( newMarker( aRefSeg, pad, padSeg, DRCE_TRACK_NEAR_PAD ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, pad, padSeg, DRCE_TRACK_NEAR_PAD ) ); if( !handleNewMarker() ) return false; @@ -455,7 +465,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // Test distance between two vias, i.e. two circles, trivial case if( EuclideanNorm( segStartPoint ) < w_dist ) { - markers.push_back( newMarker( pos, aRefSeg, track, DRCE_VIA_NEAR_VIA ) ); + markers.push_back( + m_markerFactory.NewMarker( pos, aRefSeg, track, DRCE_VIA_NEAR_VIA ) ); if( !handleNewMarker() ) return false; @@ -472,7 +483,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkMarginToCircle( segStartPoint, w_dist, delta.x ) ) { - markers.push_back( newMarker( pos, aRefSeg, track, DRCE_VIA_NEAR_TRACK ) ); + markers.push_back( + m_markerFactory.NewMarker( pos, aRefSeg, track, DRCE_VIA_NEAR_TRACK ) ); if( !handleNewMarker() ) return false; @@ -498,7 +510,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) ) continue; - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_TRACK_NEAR_VIA ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_TRACK_NEAR_VIA ) ); if( !handleNewMarker() ) return false; @@ -526,7 +539,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // Fine test : we consider the rounded shape of each end of the track segment: if( segStartPoint.x >= 0 && segStartPoint.x <= m_segmLength ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_TRACK_ENDS1 ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_TRACK_ENDS1 ) ); if( !handleNewMarker() ) return false; @@ -534,7 +548,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_TRACK_ENDS2 ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_TRACK_ENDS2 ) ); if( !handleNewMarker() ) return false; @@ -549,7 +564,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // Fine test : we consider the rounded shape of the ends if( segEndPoint.x >= 0 && segEndPoint.x <= m_segmLength ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_TRACK_ENDS3 ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_TRACK_ENDS3 ) ); if( !handleNewMarker() ) return false; @@ -557,7 +573,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_TRACK_ENDS4 ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_TRACK_ENDS4 ) ); if( !handleNewMarker() ) return false; @@ -571,7 +588,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // handled) // X.............X // O--REF--+ - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_TRACK_SEGMENTS_TOO_CLOSE ) ); + markers.push_back( m_markerFactory.NewMarker( + aRefSeg, track, seg, DRCE_TRACK_SEGMENTS_TOO_CLOSE ) ); if( !handleNewMarker() ) return false; @@ -588,7 +606,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( ( segStartPoint.y < 0 ) && ( segEndPoint.y > 0 ) ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_TRACKS_CROSSING ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_TRACKS_CROSSING ) ); if( !handleNewMarker() ) return false; @@ -597,14 +616,16 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) // At this point the drc error is due to an end near a reference segm end if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM1 ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM1 ) ); if( !handleNewMarker() ) return false; } if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM2 ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM2 ) ); if( !handleNewMarker() ) return false; @@ -633,7 +654,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkLine( segStartPoint, segEndPoint ) ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM3 ) ); + markers.push_back( + m_markerFactory.NewMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM3 ) ); if( !handleNewMarker() ) return false; @@ -662,7 +684,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkMarginToCircle( relStartPos, w_dist, delta.x ) ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM4 ) ); + markers.push_back( m_markerFactory.NewMarker( + aRefSeg, track, seg, DRCE_ENDS_PROBLEM4 ) ); if( !handleNewMarker() ) return false; @@ -670,7 +693,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( !checkMarginToCircle( relEndPos, w_dist, delta.x ) ) { - markers.push_back( newMarker( aRefSeg, track, seg, DRCE_ENDS_PROBLEM5 ) ); + markers.push_back( m_markerFactory.NewMarker( + aRefSeg, track, seg, DRCE_ENDS_PROBLEM5 ) ); if( !handleNewMarker() ) return false; @@ -701,7 +725,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) SHAPE_POLY_SET* outline = const_cast( &zone->GetFilledPolysList() ); if( outline->Distance( refSeg, aRefSeg->GetWidth() ) < clearance ) - addMarkerToPcb( newMarker( aRefSeg, zone, DRCE_TRACK_NEAR_ZONE ) ); + addMarkerToPcb( m_markerFactory.NewMarker( aRefSeg, zone, DRCE_TRACK_NEAR_ZONE ) ); } /***********************************************/ @@ -721,7 +745,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) if( test_seg.SquaredDistance( *it ) < w_dist ) { auto pt = test_seg.NearestPoint( *it ); - markers.push_back( newMarker( wxPoint( pt.x, pt.y ), aRefSeg, DRCE_TRACK_NEAR_EDGE ) ); + markers.push_back( m_markerFactory.NewMarker( + wxPoint( pt.x, pt.y ), aRefSeg, DRCE_TRACK_NEAR_EDGE ) ); if( !handleNewMarker() ) return false; @@ -793,7 +818,8 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) if( area_to_test->Outline()->Contains( end ) ) { wxPoint pos( end.x, end.y ); - m_currentMarker = newMarker( pos, aArea, area_to_test, DRCE_ZONES_INTERSECT ); + m_currentMarker = + m_markerFactory.NewMarker( pos, aArea, area_to_test, DRCE_ZONES_INTERSECT ); return false; } @@ -825,8 +851,8 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) if( d < zone_clearance ) { // COPPERAREA_COPPERAREA error : edge intersect or too close - m_currentMarker = newMarker( wxPoint( x, y ), aArea, area_to_test, - DRCE_ZONES_TOO_CLOSE ); + m_currentMarker = m_markerFactory.NewMarker( + wxPoint( x, y ), aArea, area_to_test, DRCE_ZONES_TOO_CLOSE ); return false; }