Move rest of DRC tests to kicad.
This commit is contained in:
parent
d14c6ba71f
commit
ce2937a399
|
@ -240,10 +240,17 @@ set( PCBNEW_DRC_SRCS
|
|||
drc/drc_engine.cpp
|
||||
drc/drc_rule_parser.cpp
|
||||
drc/drc_test_provider.cpp
|
||||
drc/drc_test_provider_annulus.cpp
|
||||
drc/drc_test_provider_clearance_base.cpp
|
||||
drc/drc_test_provider_disallow.cpp
|
||||
drc/drc_test_provider_connectivity.cpp
|
||||
drc/drc_test_provider_copper_clearance.cpp
|
||||
drc/drc_test_provider_edge_clearance.cpp
|
||||
drc/drc_test_provider_hole_clearance.cpp
|
||||
drc/drc_test_provider_hole_size.cpp
|
||||
drc/drc_test_provider_misc.cpp
|
||||
drc/drc_test_provider_track_width.cpp
|
||||
drc/drc_test_provider_via_diameter.cpp
|
||||
)
|
||||
|
||||
set( PCBNEW_NETLIST_SRCS
|
||||
|
|
|
@ -3,20 +3,8 @@
|
|||
#include <drc/drc_test_provider.h>
|
||||
|
||||
DRC_TEST_PROVIDER::DRC_TEST_PROVIDER() :
|
||||
m_drcEngine( nullptr ),
|
||||
m_enable( false )
|
||||
m_drcEngine( nullptr )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DRC_TEST_PROVIDER::Enable( bool enable )
|
||||
{
|
||||
m_enable = enable;
|
||||
}
|
||||
|
||||
bool DRC_TEST_PROVIDER::IsEnabled() const
|
||||
{
|
||||
return m_enable;
|
||||
}
|
||||
|
||||
const wxString DRC_TEST_PROVIDER::GetName() const { return "<no name test>"; }
|
||||
|
@ -54,7 +42,7 @@ void DRC_TEST_PROVIDER::ReportStage ( const wxString& aStageName, int index, int
|
|||
ReportAux( aStageName );
|
||||
}
|
||||
|
||||
void DRC_TEST_PROVIDER::ReportAux( const wxString& fmt, ... )
|
||||
void DRC_TEST_PROVIDER::ReportAux( wxString fmt, ... )
|
||||
{
|
||||
va_list vargs;
|
||||
va_start( vargs, fmt );
|
||||
|
|
|
@ -89,13 +89,10 @@ public:
|
|||
|
||||
virtual bool Run() = 0;
|
||||
|
||||
virtual void Enable( bool enable );
|
||||
virtual bool IsEnabled() const;
|
||||
|
||||
virtual const wxString GetName() const;
|
||||
virtual const wxString GetDescription() const;
|
||||
|
||||
virtual void ReportAux( const wxString& fmt, ... );
|
||||
virtual void ReportAux( wxString fmt, ... );
|
||||
virtual void Report( std::shared_ptr<DRC_ITEM> item );
|
||||
virtual void ReportWithMarker( std::shared_ptr<DRC_ITEM> item, wxPoint aMarkerPos );
|
||||
virtual void ReportWithMarker( std::shared_ptr<DRC_ITEM> item, VECTOR2I aMarkerPos );
|
||||
|
@ -119,11 +116,12 @@ protected:
|
|||
virtual void accountCheck( const DRC_CONSTRAINT& constraintToTest );
|
||||
virtual bool isErrorLimitExceeded( int error_code );
|
||||
|
||||
EDA_UNITS userUnits() const;
|
||||
DRC_ENGINE *m_drcEngine;
|
||||
EDA_UNITS userUnits() const;
|
||||
DRC_ENGINE* m_drcEngine;
|
||||
std::unordered_map<const DRC_RULE*, int> m_stats;
|
||||
bool m_enable;
|
||||
bool m_isRuleDriven = true;
|
||||
bool m_isRuleDriven = true;
|
||||
|
||||
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
|
||||
};
|
||||
|
||||
#endif // DRC_TEST_PROVIDER__H
|
||||
|
|
|
@ -21,19 +21,14 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_track.h>
|
||||
#include <class_pad.h>
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <class_track.h>
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_rule.h>
|
||||
#include <drc/drc_test_provider.h>
|
||||
|
||||
|
||||
/*
|
||||
Via/pad annular ring width test. Checks if there's sufficient copper ring around PTH/NPTH holes (vias/pads)
|
||||
Errors generated:
|
||||
|
@ -44,9 +39,6 @@
|
|||
- pad stack support (different IAR/OAR values depending on layer)
|
||||
*/
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
class DRC_TEST_PROVIDER_ANNULUS : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
|
@ -73,71 +65,72 @@ public:
|
|||
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
|
||||
};
|
||||
|
||||
}; // namespace test
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_ANNULUS::Run()
|
||||
bool DRC_TEST_PROVIDER_ANNULUS::Run()
|
||||
{
|
||||
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH ) )
|
||||
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH ) )
|
||||
{
|
||||
ReportAux( "No annulus constraints found. Skipping check." );
|
||||
return false;
|
||||
}
|
||||
|
||||
ReportStage( ( "Testing via annular rings" ), 0, 2 );
|
||||
ReportStage( _( "Testing via annular rings" ), 0, 2 );
|
||||
|
||||
auto checkAnnulus = [&]( BOARD_ITEM* item ) -> bool
|
||||
{
|
||||
bool fail_min = false, fail_max = false;
|
||||
int v_min, v_max;
|
||||
auto via = dyn_cast<VIA*>( item );
|
||||
auto checkAnnulus =
|
||||
[&]( BOARD_ITEM* item ) -> bool
|
||||
{
|
||||
int v_min;
|
||||
int v_max;
|
||||
VIA* via = dyn_cast<VIA*>( item );
|
||||
|
||||
// fixme: check minimum IAR/OAR ring for THT pads too
|
||||
if( !via )
|
||||
return true;
|
||||
// fixme: check minimum IAR/OAR ring for THT pads too
|
||||
if( !via )
|
||||
return true;
|
||||
|
||||
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH, via );
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH,
|
||||
via );
|
||||
int annulus = ( via->GetWidth() - via->GetDrillValue() ) / 2;
|
||||
bool fail_min = false;
|
||||
bool fail_max = false;
|
||||
|
||||
accountCheck( constraint );
|
||||
accountCheck( constraint );
|
||||
|
||||
int annulus = ( via->GetWidth() - via->GetDrillValue() ) / 2;
|
||||
if( constraint.Value().HasMin() )
|
||||
{
|
||||
v_min = constraint.Value().Min();
|
||||
fail_min = annulus < v_min;
|
||||
}
|
||||
|
||||
if( constraint.Value().HasMin() )
|
||||
{
|
||||
v_min = constraint.Value().Min();
|
||||
fail_min = annulus < v_min;
|
||||
}
|
||||
if( constraint.Value().HasMax() )
|
||||
{
|
||||
v_max = constraint.Value().Max();
|
||||
fail_max = annulus > v_max;
|
||||
}
|
||||
|
||||
if( constraint.Value().HasMax() )
|
||||
{
|
||||
v_max = constraint.Value().Max();
|
||||
fail_max = annulus > v_max;
|
||||
}
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ANNULUS );
|
||||
wxString msg;
|
||||
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ANNULUS );
|
||||
wxString msg;
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s annulus %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
fail_min ? _( "minimum" ) : _( "maximum" ),
|
||||
MessageTextFromValue( userUnits(), annulus, true ),
|
||||
MessageTextFromValue( userUnits(), fail_min ? v_min : v_max, true ) );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s; actual annulus %s, constraint %s %s)" ),
|
||||
constraint.GetParentRule()->m_Name,
|
||||
MessageTextFromValue( userUnits(), annulus, true ),
|
||||
fail_min ? _( "minimum" ) : _( "maximum" ),
|
||||
MessageTextFromValue( userUnits(), fail_min ? v_min : v_max, true ) );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
ReportWithMarker( drcItem, via->GetPosition() );
|
||||
|
||||
ReportWithMarker( drcItem, via->GetPosition() );
|
||||
if( isErrorLimitExceeded( DRCE_ANNULUS ) )
|
||||
return false;
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_ANNULUS ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
forEachGeometryItem( { PCB_VIA_T }, LSET::AllCuMask(), checkAnnulus );
|
||||
|
||||
|
@ -147,7 +140,7 @@ bool test::DRC_TEST_PROVIDER_ANNULUS::Run()
|
|||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_ANNULUS::GetMatchingConstraintIds() const
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_ANNULUS::GetMatchingConstraintIds() const
|
||||
{
|
||||
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_ANNULUS_WIDTH };
|
||||
}
|
||||
|
@ -155,5 +148,5 @@ std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_ANNULUS::GetMatchingCons
|
|||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_ANNULUS> dummy;
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_ANNULUS> dummy;
|
||||
}
|
|
@ -55,8 +55,6 @@ protected:
|
|||
BOARD* m_board;
|
||||
int m_largestClearance;
|
||||
bool m_boardOutlineValid;
|
||||
|
||||
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -42,9 +42,6 @@
|
|||
- DRCE_ZONE_HAS_EMPTY_NET
|
||||
*/
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
class DRC_TEST_PROVIDER_CONNECTIVITY : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
|
@ -71,12 +68,10 @@ public:
|
|||
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
|
||||
};
|
||||
|
||||
}; // namespace test
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_CONNECTIVITY::Run()
|
||||
bool DRC_TEST_PROVIDER_CONNECTIVITY::Run()
|
||||
{
|
||||
ReportStage( ( "Testing dangling pads/vias" ), 0, 2 );
|
||||
ReportStage( _( "Testing dangling pads/vias" ), 0, 2 );
|
||||
|
||||
BOARD* board = m_drcEngine->GetBoard();
|
||||
|
||||
|
@ -84,11 +79,11 @@ bool test::DRC_TEST_PROVIDER_CONNECTIVITY::Run()
|
|||
connectivity->Clear();
|
||||
connectivity->Build( board ); // just in case. This really needs to be reliable.
|
||||
|
||||
|
||||
for( auto track : board->Tracks() )
|
||||
for( TRACK* track : board->Tracks() )
|
||||
{
|
||||
bool exceedT = isErrorLimitExceeded( DRCE_DANGLING_TRACK );
|
||||
bool exceedV = isErrorLimitExceeded( DRCE_DANGLING_VIA );
|
||||
|
||||
// Test for dangling items
|
||||
int code = track->Type() == PCB_VIA_T ? DRCE_DANGLING_VIA : DRCE_DANGLING_TRACK;
|
||||
wxPoint pos;
|
||||
|
@ -101,10 +96,6 @@ bool test::DRC_TEST_PROVIDER_CONNECTIVITY::Run()
|
|||
if( connectivity->TestTrackEndpointDangling( track, &pos ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( code );
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( track );
|
||||
ReportWithMarker( drcItem, pos );
|
||||
}
|
||||
|
@ -113,36 +104,32 @@ bool test::DRC_TEST_PROVIDER_CONNECTIVITY::Run()
|
|||
break;
|
||||
}
|
||||
|
||||
ReportStage( ( "Testing starved zones" ), 0, 2 );
|
||||
ReportStage( _( "Testing starved zones" ), 0, 2 );
|
||||
|
||||
/* test starved zones */
|
||||
for( auto zone : board->Zones() )
|
||||
for( ZONE_CONTAINER* zone : board->Zones() )
|
||||
{
|
||||
if( !zone->IsOnCopperLayer() )
|
||||
continue;
|
||||
|
||||
int netcode = zone->GetNetCode();
|
||||
// a netcode < 0 or > 0 and no pad in net is a error or strange
|
||||
// perhaps a "dead" net, which happens when all pads in this net were removed
|
||||
// Remark: a netcode < 0 should not happen (this is more a bug somewhere)
|
||||
int pads_in_net = ( netcode > 0 ) ? connectivity->GetPadCount( netcode ) : 1;
|
||||
int netcode = zone->GetNetCode();
|
||||
// a netcode < 0 or > 0 and no pad in net is a error or strange
|
||||
// perhaps a "dead" net, which happens when all pads in this net were removed
|
||||
// Remark: a netcode < 0 should not happen (this is more a bug somewhere)
|
||||
int pads_in_net = ( netcode > 0 ) ? connectivity->GetPadCount( netcode ) : 1;
|
||||
|
||||
if( ( netcode < 0 ) || pads_in_net == 0 )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONE_HAS_EMPTY_NET );
|
||||
wxString msg;
|
||||
if( ( netcode < 0 ) || pads_in_net == 0 )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ZONE_HAS_EMPTY_NET );
|
||||
drcItem->SetItems( zone );
|
||||
ReportWithMarker( drcItem, zone->GetPosition() );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( zone );
|
||||
ReportWithMarker( drcItem, zone->GetPosition() );
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_ZONE_HAS_EMPTY_NET ) )
|
||||
break;
|
||||
}
|
||||
if( isErrorLimitExceeded( DRCE_ZONE_HAS_EMPTY_NET ) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReportStage( ( "Testing unconnected ratlines" ), 0, 2 );
|
||||
ReportStage( _( "Testing unconnected nets" ), 0, 2 );
|
||||
|
||||
connectivity->RecalculateRatsnest();
|
||||
std::vector<CN_EDGE> edges;
|
||||
|
@ -151,7 +138,6 @@ bool test::DRC_TEST_PROVIDER_CONNECTIVITY::Run()
|
|||
for( const CN_EDGE& edge : edges )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNCONNECTED_ITEMS );
|
||||
|
||||
drcItem->SetItems( edge.GetSourceNode()->Parent(), edge.GetTargetNode()->Parent() );
|
||||
ReportWithMarker( drcItem, edge.GetSourceNode()->Pos() );
|
||||
|
||||
|
@ -165,7 +151,7 @@ bool test::DRC_TEST_PROVIDER_CONNECTIVITY::Run()
|
|||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_CONNECTIVITY::GetMatchingConstraintIds() const
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_CONNECTIVITY::GetMatchingConstraintIds() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
@ -173,5 +159,5 @@ std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_CONNECTIVITY::GetMatchin
|
|||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_CONNECTIVITY> dummy;
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_CONNECTIVITY> dummy;
|
||||
}
|
|
@ -21,18 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <class_board.h>
|
||||
//#include <class_drawsegment.h>
|
||||
//#include <class_pad.h>
|
||||
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
//#include <geometry/polygon_test_point_inside.h>
|
||||
//#include <geometry/seg.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
//#include <geometry/shape_rect.h>
|
||||
//#include <geometry/shape_segment.h>
|
||||
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc.h>
|
||||
#include <drc/drc_item.h>
|
||||
|
@ -85,6 +74,7 @@ private:
|
|||
|
||||
void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
|
||||
{
|
||||
// Detects missing (or malformed) footprint courtyards
|
||||
ReportStage( _( "Testing component courtyard definitions" ), 0, 2 );
|
||||
|
||||
for( MODULE* footprint : m_board->Modules() )
|
||||
|
@ -98,7 +88,6 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testFootprintCourtyardDefinitions()
|
|||
continue;
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_COURTYARD );
|
||||
|
||||
drcItem->SetItems( footprint );
|
||||
ReportWithMarker( drcItem, footprint->GetPosition() );
|
||||
}
|
||||
|
@ -130,66 +119,66 @@ void DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testOverlappingComponentCourtyards()
|
|||
ReportStage( _( "Testing component courtyard overlap" ), 0, 2 );
|
||||
|
||||
for( auto it1 = m_board->Modules().begin(); it1 != m_board->Modules().end(); it1++ )
|
||||
{
|
||||
MODULE* footprint = *it1;
|
||||
SHAPE_POLY_SET& footprintFront = footprint->GetPolyCourtyardFront();
|
||||
SHAPE_POLY_SET& footprintBack = footprint->GetPolyCourtyardBack();
|
||||
|
||||
if( footprintFront.OutlineCount() == 0 && footprintBack.OutlineCount() == 0 )
|
||||
continue; // No courtyards defined
|
||||
|
||||
for( auto it2 = it1 + 1; it2 != m_board->Modules().end(); it2++ )
|
||||
{
|
||||
MODULE* footprint = *it1;
|
||||
SHAPE_POLY_SET& footprintFront = footprint->GetPolyCourtyardFront();
|
||||
SHAPE_POLY_SET& footprintBack = footprint->GetPolyCourtyardBack();
|
||||
MODULE* test = *it2;
|
||||
SHAPE_POLY_SET& testFront = test->GetPolyCourtyardFront();
|
||||
SHAPE_POLY_SET& testBack = test->GetPolyCourtyardBack();
|
||||
SHAPE_POLY_SET intersection;
|
||||
bool overlap = false;
|
||||
wxPoint pos;
|
||||
|
||||
if( footprintFront.OutlineCount() == 0 && footprintBack.OutlineCount() == 0 )
|
||||
continue; // No courtyards defined
|
||||
|
||||
for( auto it2 = it1 + 1; it2 != m_board->Modules().end(); it2++ )
|
||||
if( footprintFront.OutlineCount() > 0 && testFront.OutlineCount() > 0
|
||||
&& footprintFront.BBoxFromCaches().Intersects( testFront.BBoxFromCaches() ) )
|
||||
{
|
||||
MODULE* test = *it2;
|
||||
SHAPE_POLY_SET& testFront = test->GetPolyCourtyardFront();
|
||||
SHAPE_POLY_SET& testBack = test->GetPolyCourtyardBack();
|
||||
SHAPE_POLY_SET intersection;
|
||||
bool overlap = false;
|
||||
wxPoint pos;
|
||||
intersection.RemoveAllContours();
|
||||
intersection.Append( footprintFront );
|
||||
|
||||
if( footprintFront.OutlineCount() > 0 && testFront.OutlineCount() > 0
|
||||
&& footprintFront.BBoxFromCaches().Intersects( testFront.BBoxFromCaches() ) )
|
||||
// Build the common area between footprint and the test:
|
||||
intersection.BooleanIntersection( testFront, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
// If the intersection exists then they overlap
|
||||
if( intersection.OutlineCount() > 0 )
|
||||
{
|
||||
intersection.RemoveAllContours();
|
||||
intersection.Append( footprintFront );
|
||||
|
||||
// Build the common area between footprint and the test:
|
||||
intersection.BooleanIntersection( testFront, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
// If the intersection exists then they overlap
|
||||
if( intersection.OutlineCount() > 0 )
|
||||
{
|
||||
overlap = true;
|
||||
pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( footprintBack.OutlineCount() > 0 && testBack.OutlineCount() > 0
|
||||
&& footprintBack.BBoxFromCaches().Intersects( testBack.BBoxFromCaches() ) )
|
||||
{
|
||||
intersection.RemoveAllContours();
|
||||
intersection.Append( footprintBack );
|
||||
|
||||
intersection.BooleanIntersection( testBack, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
if( intersection.OutlineCount() > 0 )
|
||||
{
|
||||
overlap = true;
|
||||
pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( overlap )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS );
|
||||
drcItem->SetItems( footprint, test );
|
||||
ReportWithMarker ( drcItem, pos );
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_OVERLAPPING_FOOTPRINTS ) )
|
||||
return;
|
||||
overlap = true;
|
||||
pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( footprintBack.OutlineCount() > 0 && testBack.OutlineCount() > 0
|
||||
&& footprintBack.BBoxFromCaches().Intersects( testBack.BBoxFromCaches() ) )
|
||||
{
|
||||
intersection.RemoveAllContours();
|
||||
intersection.Append( footprintBack );
|
||||
|
||||
intersection.BooleanIntersection( testBack, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
if( intersection.OutlineCount() > 0 )
|
||||
{
|
||||
overlap = true;
|
||||
pos = (wxPoint) intersection.CVertex( 0, 0, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( overlap )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS );
|
||||
drcItem->SetItems( footprint, test );
|
||||
ReportWithMarker ( drcItem, pos );
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_OVERLAPPING_FOOTPRINTS ) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <class_board.h>
|
||||
//#include <class_board.h>
|
||||
#include <common.h>
|
||||
|
||||
#include <geometry/shape.h>
|
||||
//#include <geometry/shape.h>
|
||||
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc.h>
|
||||
|
@ -38,9 +38,6 @@
|
|||
- DRCE_ALLOWED_ITEMS
|
||||
*/
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
class DRC_TEST_PROVIDER_DISALLOW : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
|
@ -65,14 +62,10 @@ public:
|
|||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}; // namespace test
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_DISALLOW::Run()
|
||||
bool DRC_TEST_PROVIDER_DISALLOW::Run()
|
||||
{
|
||||
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW ) )
|
||||
{
|
||||
|
@ -80,26 +73,28 @@ bool test::DRC_TEST_PROVIDER_DISALLOW::Run()
|
|||
return false;
|
||||
}
|
||||
|
||||
ReportStage( ("Testing for disallow constraints"), 0, 2 );
|
||||
ReportStage( _( "Testing disallow constraints" ), 0, 2 );
|
||||
|
||||
auto checkItem = [&] ( BOARD_ITEM *item ) -> bool
|
||||
auto checkItem = [&]( BOARD_ITEM *item ) -> bool
|
||||
{
|
||||
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW,
|
||||
item );
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_DISALLOW, item );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
|
||||
wxString msg;
|
||||
if( constraint.m_DisallowFlags )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), constraint.GetParentRule()->m_Name );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ),
|
||||
constraint.GetName() );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
ReportWithMarker( drcItem, item->GetPosition() );
|
||||
ReportWithMarker( drcItem, item->GetPosition() );
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_ALLOWED_ITEMS ) )
|
||||
return false;
|
||||
if( isErrorLimitExceeded( DRCE_ALLOWED_ITEMS ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
@ -112,7 +107,7 @@ bool test::DRC_TEST_PROVIDER_DISALLOW::Run()
|
|||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_DISALLOW::GetMatchingConstraintIds() const
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_DISALLOW::GetMatchingConstraintIds() const
|
||||
{
|
||||
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_DISALLOW };
|
||||
}
|
||||
|
@ -120,5 +115,5 @@ std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_DISALLOW::GetMatchingCon
|
|||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_DISALLOW> dummy;
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_DISALLOW> dummy;
|
||||
}
|
|
@ -39,8 +39,6 @@
|
|||
TODO: vias-in-smd-pads check
|
||||
*/
|
||||
|
||||
namespace test {
|
||||
|
||||
class DRC_TEST_PROVIDER_HOLE_CLEARANCE : public DRC_TEST_PROVIDER_CLEARANCE_BASE
|
||||
{
|
||||
public:
|
||||
|
@ -80,7 +78,7 @@ private:
|
|||
|
||||
struct DRILLED_HOLE
|
||||
{
|
||||
VECTOR2I m_location;
|
||||
VECTOR2I m_location;
|
||||
int m_drillRadius = 0;
|
||||
BOARD_ITEM* m_owner = nullptr;
|
||||
};
|
||||
|
@ -91,10 +89,8 @@ private:
|
|||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run()
|
||||
bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run()
|
||||
{
|
||||
m_board = m_drcEngine->GetBoard();
|
||||
|
||||
|
@ -130,11 +126,8 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::Run()
|
|||
}
|
||||
|
||||
|
||||
void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::buildDrilledHoleList()
|
||||
void DRC_TEST_PROVIDER_HOLE_CLEARANCE::buildDrilledHoleList()
|
||||
{
|
||||
bool success = true;
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
m_drilledHoles.clear();
|
||||
|
||||
for( MODULE* module : m_board->Modules() )
|
||||
|
@ -155,7 +148,7 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::buildDrilledHoleList()
|
|||
|
||||
for( TRACK* track : m_board->Tracks() )
|
||||
{
|
||||
if ( track->Type() == PCB_VIA_T )
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
VIA* via = static_cast<VIA*>( track );
|
||||
addHole( via->GetPosition(), via->GetDrillValue() / 2, via );
|
||||
|
@ -163,10 +156,9 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::buildDrilledHoleList()
|
|||
}
|
||||
|
||||
ReportAux( "Total drilled holes : %d", m_drilledHoles.size() );
|
||||
|
||||
}
|
||||
|
||||
void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testPads2Holes()
|
||||
void DRC_TEST_PROVIDER_HOLE_CLEARANCE::testPads2Holes()
|
||||
{
|
||||
std::vector<D_PAD*> sortedPads;
|
||||
|
||||
|
@ -206,7 +198,7 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testPads2Holes()
|
|||
}
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad, D_PAD** aStart,
|
||||
bool DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad, D_PAD** aStart,
|
||||
D_PAD** aEnd, int x_limit )
|
||||
{
|
||||
const static LSET all_cu = LSET::AllCuMask();
|
||||
|
@ -329,7 +321,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::doPadToPadHoleDrc( D_PAD* aRefPad,
|
|||
}
|
||||
|
||||
|
||||
void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::addHole( const VECTOR2I& aLocation, int aRadius,
|
||||
void DRC_TEST_PROVIDER_HOLE_CLEARANCE::addHole( const VECTOR2I& aLocation, int aRadius,
|
||||
BOARD_ITEM* aOwner )
|
||||
{
|
||||
DRILLED_HOLE hole;
|
||||
|
@ -344,7 +336,7 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::addHole( const VECTOR2I& aLocation,
|
|||
}
|
||||
|
||||
|
||||
void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
|
||||
void DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
|
||||
{
|
||||
// Sort holes by X for performance. In the nested iteration we then need to look at
|
||||
// following holes only while they are within the refHole's neighborhood as defined by
|
||||
|
@ -407,7 +399,7 @@ void test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoles2Holes()
|
|||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetMatchingConstraintIds() const
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetMatchingConstraintIds() const
|
||||
{
|
||||
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE };
|
||||
}
|
||||
|
@ -415,5 +407,5 @@ std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_CLEARANCE::GetMatch
|
|||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_HOLE_CLEARANCE> dummy;
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_HOLE_CLEARANCE> dummy;
|
||||
}
|
||||
|
|
|
@ -21,23 +21,12 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_drawsegment.h>
|
||||
#include <class_pad.h>
|
||||
#include <common.h>
|
||||
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
#include <geometry/polygon_test_point_inside.h>
|
||||
#include <geometry/seg.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <geometry/shape_segment.h>
|
||||
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_rule.h>
|
||||
#include <drc/drc.h>
|
||||
#include <pcbnew/drc/drc_test_provider_clearance_base.h>
|
||||
#include <drc/drc_test_provider_clearance_base.h>
|
||||
|
||||
|
||||
/*
|
||||
|
@ -49,9 +38,6 @@
|
|||
TODO: max drill size check
|
||||
*/
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
class DRC_TEST_PROVIDER_HOLE_SIZE : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
|
@ -85,38 +71,34 @@ private:
|
|||
BOARD* m_board;
|
||||
};
|
||||
|
||||
}; // namespace test
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_HOLE_SIZE::Run()
|
||||
bool DRC_TEST_PROVIDER_HOLE_SIZE::Run()
|
||||
{
|
||||
ReportStage( ( "Testing pad holes" ), 0, 2 );
|
||||
ReportStage( _( "Testing pad holes" ), 0, 2 );
|
||||
|
||||
m_board = m_drcEngine->GetBoard();
|
||||
|
||||
for( auto module : m_board->Modules() )
|
||||
for( MODULE* module : m_board->Modules() )
|
||||
{
|
||||
for( auto pad : module->Pads() )
|
||||
for( D_PAD* pad : module->Pads() )
|
||||
{
|
||||
if( checkPad( pad ) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReportStage( ( "Testing via/microvia holes" ), 0, 2 );
|
||||
ReportStage( _( "Testing via/microvia holes" ), 0, 2 );
|
||||
|
||||
std::vector<VIA*> vias;
|
||||
|
||||
for( auto track : m_board->Tracks() )
|
||||
for( TRACK* track : m_board->Tracks() )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
vias.push_back( static_cast<VIA*>( track ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for( auto via : vias )
|
||||
for( VIA* via : vias )
|
||||
{
|
||||
if( checkVia( via ) )
|
||||
break;
|
||||
|
@ -128,30 +110,30 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::Run()
|
|||
}
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
|
||||
bool DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
|
||||
{
|
||||
int holeSize = std::min( aPad->GetDrillSize().x, aPad->GetDrillSize().y );
|
||||
|
||||
if( holeSize == 0 )
|
||||
return true;
|
||||
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, aPad );
|
||||
auto minHole = constraint.GetValue().Min();
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_HOLE_SIZE, aPad );
|
||||
int minHole = constraint.GetValue().Min();
|
||||
|
||||
accountCheck( constraint );
|
||||
|
||||
if( holeSize < minHole )
|
||||
{
|
||||
wxString msg;
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_DRILL );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), minHole, true ),
|
||||
MessageTextFromValue( userUnits(), holeSize, true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), minHole, true ),
|
||||
MessageTextFromValue( userUnits(), holeSize, true ) );
|
||||
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( aPad );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
ReportWithMarker( drcItem, aPad->GetPosition() );
|
||||
|
||||
|
@ -162,28 +144,28 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( D_PAD* aPad )
|
|||
}
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
|
||||
bool DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
|
||||
{
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE, via );
|
||||
auto minHole = constraint.GetValue().Min();
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_HOLE_SIZE, via );
|
||||
int minHole = constraint.GetValue().Min();
|
||||
|
||||
accountCheck( constraint );
|
||||
|
||||
if( via->GetDrillValue() < minHole )
|
||||
{
|
||||
wxString msg;
|
||||
int errorCode = via->GetViaType() == VIATYPE::MICROVIA ? DRCE_TOO_SMALL_MICROVIA_DRILL :
|
||||
DRCE_TOO_SMALL_DRILL;
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( errorCode );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), minHole, true ),
|
||||
MessageTextFromValue( userUnits(), via->GetDrillValue(), true ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
MessageTextFromValue( userUnits(), minHole, true ),
|
||||
MessageTextFromValue( userUnits(), via->GetDrillValue(), true ) );
|
||||
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( via );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
ReportWithMarker( drcItem, via->GetPosition() );
|
||||
|
||||
|
@ -194,7 +176,7 @@ bool test::DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( VIA* via )
|
|||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingConstraintIds() const
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingConstraintIds() const
|
||||
{
|
||||
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_HOLE_SIZE };
|
||||
}
|
||||
|
@ -202,5 +184,5 @@ std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_HOLE_SIZE::GetMatchingCo
|
|||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_HOLE_SIZE> dummy;
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_HOLE_SIZE> dummy;
|
||||
}
|
|
@ -22,10 +22,7 @@
|
|||
*/
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_track.h>
|
||||
#include <common.h>
|
||||
|
||||
#include <pcbnew/drc/drc_engine.h>
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_rule.h>
|
||||
|
@ -47,9 +44,6 @@
|
|||
- cross-check PCB fields against SCH fields
|
||||
*/
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
class DRC_TEST_PROVIDER_LVS : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
|
@ -82,20 +76,19 @@ private:
|
|||
void testFootprints( NETLIST& aNetlist );
|
||||
};
|
||||
|
||||
}; // namespace test
|
||||
|
||||
|
||||
void test::DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
|
||||
void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
|
||||
{
|
||||
wxString msg;
|
||||
BOARD* board = m_drcEngine->GetBoard();
|
||||
BOARD* board = m_drcEngine->GetBoard();
|
||||
|
||||
auto comp = []( const MODULE* x, const MODULE* y ) {
|
||||
return x->GetReference().CmpNoCase( y->GetReference() ) < 0;
|
||||
};
|
||||
auto comp = []( const MODULE* x, const MODULE* y )
|
||||
{
|
||||
return x->GetReference().CmpNoCase( y->GetReference() ) < 0;
|
||||
};
|
||||
|
||||
auto mods = std::set<MODULE*, decltype( comp )>( comp );
|
||||
|
||||
// Search for duplicate footprints on the board
|
||||
for( MODULE* mod : board->Modules() )
|
||||
{
|
||||
auto ins = mods.insert( mod );
|
||||
|
@ -120,21 +113,82 @@ void test::DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
|
|||
|
||||
if( module == nullptr )
|
||||
{
|
||||
msg.Printf( _( "Missing footprint %s (%s)" ), component->GetReference(),
|
||||
m_msg.Printf( _( "Missing footprint %s (%s)" ), component->GetReference(),
|
||||
component->GetValue() );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_FOOTPRINT );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
Report( drcItem );
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_MISSING_FOOTPRINT ) )
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( D_PAD* pad : module->Pads() )
|
||||
{
|
||||
const COMPONENT_NET& sch_net = component->GetNet( pad->GetName() );
|
||||
const wxString& pcb_netname = pad->GetNetname();
|
||||
|
||||
if( !pcb_netname.IsEmpty() && sch_net.GetPinName().IsEmpty() )
|
||||
{
|
||||
m_msg.Printf( _( "No corresponding pin found in schematic." ) );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( pad );
|
||||
ReportWithMarker( drcItem, module->GetPosition() );
|
||||
}
|
||||
else if( pcb_netname.IsEmpty() && !sch_net.GetNetName().IsEmpty() )
|
||||
{
|
||||
m_msg.Printf( _( "Pad missing net given by schematic (%s)." ),
|
||||
sch_net.GetNetName() );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( pad );
|
||||
ReportWithMarker( drcItem, module->GetPosition() );
|
||||
}
|
||||
else if( pcb_netname != sch_net.GetNetName() )
|
||||
{
|
||||
m_msg.Printf( _( "Pad net (%s) doesn't match net given by schematic (%s)." ),
|
||||
pcb_netname,
|
||||
sch_net.GetNetName() );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( pad );
|
||||
ReportWithMarker( drcItem, module->GetPosition() );
|
||||
}
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_NET_CONFLICT ) )
|
||||
break;
|
||||
}
|
||||
|
||||
for( unsigned jj = 0; jj < component->GetNetCount(); ++jj )
|
||||
{
|
||||
const COMPONENT_NET& sch_net = component->GetNet( jj );
|
||||
|
||||
if( !module->FindPadByName( sch_net.GetPinName() ) )
|
||||
{
|
||||
m_msg.Printf( _( "No pad found for pin %s in schematic." ),
|
||||
sch_net.GetPinName() );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( module );
|
||||
ReportWithMarker( drcItem, module->GetPosition() );
|
||||
}
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_NET_CONFLICT ) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for( auto module : mods )
|
||||
// Search for component footprints found on board but not in netlist.
|
||||
for( MODULE* module : board->Modules() )
|
||||
{
|
||||
COMPONENT* component = aNetlist.GetComponentByReference( module->GetReference() );
|
||||
|
||||
|
@ -152,7 +206,7 @@ void test::DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
|
|||
}
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_LVS::fetchNetlistFromSchematic( NETLIST& aNetlist )
|
||||
bool DRC_TEST_PROVIDER_LVS::fetchNetlistFromSchematic( NETLIST& aNetlist )
|
||||
{
|
||||
// fixme: make it work without dependency on EDIT_FRAME/kiway
|
||||
#if 0
|
||||
|
@ -177,7 +231,7 @@ bool test::DRC_TEST_PROVIDER_LVS::fetchNetlistFromSchematic( NETLIST& aNetlist )
|
|||
return false;
|
||||
}
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_LVS::Run()
|
||||
bool DRC_TEST_PROVIDER_LVS::Run()
|
||||
{
|
||||
ReportStage( _( "Layout-vs-Schematic checks..." ), 0, 2 );
|
||||
|
||||
|
@ -203,7 +257,7 @@ bool test::DRC_TEST_PROVIDER_LVS::Run()
|
|||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_LVS::GetMatchingConstraintIds() const
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_LVS::GetMatchingConstraintIds() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
@ -211,5 +265,5 @@ std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_LVS::GetMatchingConstrai
|
|||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_LVS> dummy;
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_LVS> dummy;
|
||||
}
|
|
@ -21,18 +21,12 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_track.h>
|
||||
#include <common.h>
|
||||
|
||||
#include <class_module.h>
|
||||
#include <class_pcb_text.h>
|
||||
|
||||
#include <pcbnew/drc/drc_engine.h>
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_rule.h>
|
||||
#include <pcbnew/drc/drc_test_provider.h>
|
||||
#include <drc/drc_test_provider.h>
|
||||
|
||||
#include <ws_draw_item.h>
|
||||
#include <ws_proxy_view_item.h>
|
||||
|
@ -48,9 +42,6 @@
|
|||
- if grows too big, split into separate providers
|
||||
*/
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
class DRC_TEST_PROVIDER_MISC : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
|
@ -85,10 +76,8 @@ private:
|
|||
BOARD* m_board;
|
||||
};
|
||||
|
||||
}; // namespace test
|
||||
|
||||
|
||||
void test::DRC_TEST_PROVIDER_MISC::testOutline()
|
||||
void DRC_TEST_PROVIDER_MISC::testOutline()
|
||||
{
|
||||
wxPoint error_loc( m_board->GetBoardEdgesBoundingBox().GetPosition() );
|
||||
|
||||
|
@ -98,80 +87,86 @@ void test::DRC_TEST_PROVIDER_MISC::testOutline()
|
|||
return;
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (not a closed shape)" ) );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (not a closed shape)" ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( m_board );
|
||||
|
||||
ReportWithMarker( drcItem, error_loc );
|
||||
}
|
||||
|
||||
|
||||
void test::DRC_TEST_PROVIDER_MISC::testDisabledLayers()
|
||||
void DRC_TEST_PROVIDER_MISC::testDisabledLayers()
|
||||
{
|
||||
LSET disabledLayers = m_board->GetEnabledLayers().flip();
|
||||
|
||||
|
||||
// Perform the test only for copper layers
|
||||
disabledLayers &= LSET::AllCuMask();
|
||||
|
||||
auto checkDisabledLayers = [&]( BOARD_ITEM* item ) -> bool {
|
||||
LSET refLayers ( item->GetLayer() );
|
||||
auto checkDisabledLayers =
|
||||
[&]( BOARD_ITEM* item ) -> bool
|
||||
{
|
||||
LSET refLayers ( item->GetLayer() );
|
||||
|
||||
if( ( disabledLayers & refLayers ).any() )
|
||||
{
|
||||
wxString msg;
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_DISABLED_LAYER_ITEM );
|
||||
if( ( disabledLayers & refLayers ).any() )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM>drcItem = DRC_ITEM::Create( DRCE_DISABLED_LAYER_ITEM );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (layer %s)" ), item->GetLayerName() );
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (layer %s)" ),
|
||||
item->GetLayerName() );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( item );
|
||||
|
||||
ReportWithMarker( drcItem, item->GetPosition() );
|
||||
}
|
||||
return true;
|
||||
};
|
||||
ReportWithMarker( drcItem, item->GetPosition() );
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// fixme: what about graphical items?
|
||||
forEachGeometryItem( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_ZONE_AREA_T, PCB_PAD_T },
|
||||
LSET::AllLayersMask(), checkDisabledLayers );
|
||||
LSET::AllLayersMask(), checkDisabledLayers );
|
||||
}
|
||||
|
||||
void test::DRC_TEST_PROVIDER_MISC::testTextVars()
|
||||
void DRC_TEST_PROVIDER_MISC::testTextVars()
|
||||
{
|
||||
auto checkUnresolvedTextVar = [&]( EDA_ITEM* item ) -> bool {
|
||||
EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item );
|
||||
auto checkUnresolvedTextVar =
|
||||
[&]( EDA_ITEM* item ) -> bool
|
||||
{
|
||||
EDA_TEXT* text = dynamic_cast<EDA_TEXT*>( item );
|
||||
|
||||
assert( text );
|
||||
wxASSERT( text );
|
||||
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
if( isErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
|
||||
return false;
|
||||
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
if( isErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
|
||||
return false;
|
||||
std::shared_ptr<DRC_ITEM>drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
|
||||
drcItem->SetItems( item );
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
|
||||
drcItem->SetItems( item );
|
||||
ReportWithMarker( drcItem, item->GetPosition() );
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
ReportWithMarker( drcItem, item->GetPosition() );
|
||||
}
|
||||
return true;
|
||||
};
|
||||
forEachGeometryItem( { PCB_MODULE_TEXT_T, PCB_TEXT_T }, LSET::AllLayersMask(),
|
||||
checkUnresolvedTextVar );
|
||||
|
||||
forEachGeometryItem(
|
||||
{ PCB_MODULE_TEXT_T, PCB_TEXT_T }, LSET::AllLayersMask(), checkUnresolvedTextVar );
|
||||
|
||||
WS_DRAW_ITEM_LIST wsItems;
|
||||
|
||||
auto worksheet = m_drcEngine->GetWorksheet();
|
||||
KIGFX::WS_PROXY_VIEW_ITEM* worksheet = m_drcEngine->GetWorksheet();
|
||||
WS_DRAW_ITEM_LIST wsItems;
|
||||
|
||||
if( !worksheet )
|
||||
return;
|
||||
|
||||
wsItems.SetMilsToIUfactor( IU_PER_MILS );
|
||||
wsItems.SetSheetNumber( 1 );
|
||||
wsItems.SetSheetCount( 1 );
|
||||
wsItems.SetFileName( "dummyFilename" );
|
||||
wsItems.SetSheetName( "dummySheet" );
|
||||
wsItems.SetSheetLayer( "dummyLayer" );
|
||||
wsItems.SetProject( m_board->GetProject() );
|
||||
wsItems.BuildWorkSheetGraphicList( worksheet->GetPageInfo(), worksheet->GetTitleBlock() );
|
||||
|
||||
for( WS_DRAW_ITEM_BASE* item = wsItems.GetFirst(); item; item = wsItems.GetNext() )
|
||||
|
@ -181,16 +176,19 @@ void test::DRC_TEST_PROVIDER_MISC::testTextVars()
|
|||
if( isErrorLimitExceeded( DRCE_UNRESOLVED_VARIABLE ) )
|
||||
return;
|
||||
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
|
||||
drcItem->SetItems( text );
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE );
|
||||
drcItem->SetItems( text );
|
||||
|
||||
ReportWithMarker( drcItem, text->GetPosition() );
|
||||
ReportWithMarker( drcItem, text->GetPosition() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_MISC::Run()
|
||||
bool DRC_TEST_PROVIDER_MISC::Run()
|
||||
{
|
||||
m_board = m_drcEngine->GetBoard();
|
||||
|
||||
|
@ -207,7 +205,7 @@ bool test::DRC_TEST_PROVIDER_MISC::Run()
|
|||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_MISC::GetMatchingConstraintIds() const
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_MISC::GetMatchingConstraintIds() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
@ -215,5 +213,5 @@ std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_MISC::GetMatchingConstra
|
|||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_MISC> dummy;
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_MISC> dummy;
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2020 KiCad Developers.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
//#include <common.h>
|
||||
#include <class_track.h>
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_rule.h>
|
||||
#include <drc/drc_test_provider.h>
|
||||
|
||||
|
||||
/*
|
||||
Track width test. As the name says, checks width of the tracks (including segments and arcs)
|
||||
Errors generated:
|
||||
- DRCE_TRACK_WIDTH
|
||||
*/
|
||||
|
||||
class DRC_TEST_PROVIDER_TRACK_WIDTH : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
DRC_TEST_PROVIDER_TRACK_WIDTH()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~DRC_TEST_PROVIDER_TRACK_WIDTH()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Run() override;
|
||||
|
||||
virtual const wxString GetName() const override
|
||||
{
|
||||
return "width";
|
||||
};
|
||||
|
||||
virtual const wxString GetDescription() const override
|
||||
{
|
||||
return "Tests track widths";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
|
||||
};
|
||||
|
||||
|
||||
bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
|
||||
{
|
||||
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH ) )
|
||||
{
|
||||
ReportAux( "No track width constraints found. Skipping check." );
|
||||
return false;
|
||||
}
|
||||
|
||||
ReportStage( _( "Testing track widths" ), 0, 2 );
|
||||
|
||||
auto checkTrackWidth =
|
||||
[&]( BOARD_ITEM* item ) -> bool
|
||||
{
|
||||
int actual;
|
||||
VECTOR2I p0;
|
||||
|
||||
if( ARC* arc = dyn_cast<ARC*>( item ) )
|
||||
{
|
||||
actual = arc->GetWidth();
|
||||
p0 = arc->GetStart();
|
||||
}
|
||||
else if( TRACK* trk = dyn_cast<TRACK*>( item ) )
|
||||
{
|
||||
actual = trk->GetWidth();
|
||||
p0 = ( trk->GetStart() + trk->GetEnd() ) / 2;
|
||||
}
|
||||
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
|
||||
item );
|
||||
bool fail_min = false;
|
||||
bool fail_max = false;
|
||||
int constraintWidth;
|
||||
|
||||
if( constraint.Value().HasMin() && actual < constraint.Value().Min() )
|
||||
{
|
||||
fail_min = true;
|
||||
constraintWidth = constraint.Value().Min();
|
||||
}
|
||||
|
||||
if( constraint.Value().HasMax() && actual > constraint.Value().Max() )
|
||||
{
|
||||
fail_max = true;
|
||||
constraintWidth = constraint.Value().Max();
|
||||
}
|
||||
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TRACK_WIDTH );
|
||||
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s width %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
fail_min ? _( "minimum" ) : _( "maximum" ),
|
||||
MessageTextFromValue( userUnits(), constraintWidth, true ) );
|
||||
MessageTextFromValue( userUnits(), actual, true ),
|
||||
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
ReportWithMarker( drcItem, p0 );
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_TRACK_WIDTH ) )
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
forEachGeometryItem( { PCB_TRACE_T, PCB_ARC_T }, LSET::AllCuMask(), checkTrackWidth );
|
||||
|
||||
reportRuleStatistics();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_TRACK_WIDTH::GetMatchingConstraintIds() const
|
||||
{
|
||||
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH };
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_TRACK_WIDTH> dummy;
|
||||
}
|
|
@ -21,10 +21,8 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <class_board.h>
|
||||
//#include <common.h>
|
||||
#include <class_track.h>
|
||||
#include <common.h>
|
||||
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc.h>
|
||||
#include <drc/drc_item.h>
|
||||
|
@ -40,9 +38,6 @@
|
|||
- DRCE_TOO_SMALL_MICROVIA
|
||||
*/
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
class DRC_TEST_PROVIDER_VIA_DIAMETER : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
|
@ -69,12 +64,10 @@ public:
|
|||
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
|
||||
};
|
||||
|
||||
}; // namespace test
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
|
||||
bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
|
||||
{
|
||||
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER ) )
|
||||
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_VIA_DIAMETER ) )
|
||||
{
|
||||
ReportAux( "No diameter constraints found. Skipping check." );
|
||||
return false;
|
||||
|
@ -82,55 +75,57 @@ bool test::DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
|
|||
|
||||
ReportStage( ( "Testing via diameters" ), 0, 2 );
|
||||
|
||||
auto checkViaDiameter = [&]( BOARD_ITEM* item ) -> bool {
|
||||
auto via = dyn_cast<VIA*>( item );
|
||||
auto checkViaDiameter =
|
||||
[&]( BOARD_ITEM* item ) -> bool
|
||||
{
|
||||
auto via = dyn_cast<VIA*>( item );
|
||||
|
||||
// fixme: move to pad stack check?
|
||||
if( !via )
|
||||
return true;
|
||||
// fixme: move to pad stack check?
|
||||
if( !via )
|
||||
return true;
|
||||
|
||||
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER, item );
|
||||
auto constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_VIA_DIAMETER,
|
||||
item );
|
||||
bool fail_min = false;
|
||||
bool fail_max = false;
|
||||
int constraintDiameter;
|
||||
int actual = via->GetWidth();
|
||||
|
||||
bool fail_min = false, fail_max = false;
|
||||
int constraintDiameter;
|
||||
int diameter = via->GetWidth();
|
||||
if( constraint.Value().HasMin() && actual < constraint.Value().Min() )
|
||||
{
|
||||
fail_min = true;
|
||||
constraintDiameter = constraint.Value().Min();
|
||||
}
|
||||
|
||||
if( constraint.Value().HasMin() && diameter < constraint.Value().Min() )
|
||||
{
|
||||
fail_min = true;
|
||||
constraintDiameter = constraint.Value().Min();
|
||||
}
|
||||
if( constraint.Value().HasMax() && actual > constraint.Value().Max() )
|
||||
{
|
||||
fail_max = true;
|
||||
constraintDiameter = constraint.Value().Max();
|
||||
}
|
||||
|
||||
if( constraint.Value().HasMax() && diameter > constraint.Value().Max() )
|
||||
{
|
||||
fail_max = true;
|
||||
constraintDiameter = constraint.Value().Max();
|
||||
}
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_VIA_DIAMETER );
|
||||
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_VIA_DIAMETER );
|
||||
wxString msg;
|
||||
m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s diameter %s; actual %s)" ),
|
||||
constraint.GetName(),
|
||||
fail_min ? _( "minimum" ) : _( "maximum" ),
|
||||
MessageTextFromValue( userUnits(), constraintDiameter, true ) );
|
||||
MessageTextFromValue( userUnits(), actual, true ),
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s; diameter %s, constraint %s %s)" ),
|
||||
constraint.GetParentRule()->m_Name,
|
||||
MessageTextFromValue( userUnits(), diameter, true ),
|
||||
fail_min ? _( "minimum" ) : _( "maximum" ),
|
||||
MessageTextFromValue( userUnits(), constraintDiameter, true ) );
|
||||
drcItem->SetErrorMessage( m_msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
ReportWithMarker( drcItem, via->GetPosition() );
|
||||
|
||||
ReportWithMarker( drcItem, via->GetPosition() );
|
||||
if( isErrorLimitExceeded( DRCE_VIA_DIAMETER ) )
|
||||
return false;
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_VIA_DIAMETER ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
forEachGeometryItem( { PCB_VIA_T }, LSET::AllCuMask(), checkViaDiameter );
|
||||
|
||||
|
@ -140,7 +135,7 @@ bool test::DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
|
|||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_VIA_DIAMETER::GetMatchingConstraintIds() const
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> DRC_TEST_PROVIDER_VIA_DIAMETER::GetMatchingConstraintIds() const
|
||||
{
|
||||
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_VIA_DIAMETER };
|
||||
}
|
||||
|
@ -148,5 +143,5 @@ std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_VIA_DIAMETER::GetMatchin
|
|||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_VIA_DIAMETER> dummy;
|
||||
static DRC_REGISTER_TEST_PROVIDER<DRC_TEST_PROVIDER_VIA_DIAMETER> dummy;
|
||||
}
|
|
@ -34,7 +34,6 @@ endif()
|
|||
|
||||
|
||||
add_executable( drc_proto
|
||||
drc_rules_proto_keywords.cpp
|
||||
drc_proto_test.cpp
|
||||
../../pcbnew/drc/drc_rule.cpp
|
||||
../../pcbnew/drc/drc_rule_parser.cpp
|
||||
|
@ -43,15 +42,15 @@ add_executable( drc_proto
|
|||
../../pcbnew/drc/drc_test_provider_copper_clearance.cpp
|
||||
../../pcbnew/drc/drc_test_provider_hole_clearance.cpp
|
||||
../../pcbnew/drc/drc_test_provider_edge_clearance.cpp
|
||||
drc_test_provider_hole_size.cpp
|
||||
drc_test_provider_disallow.cpp
|
||||
drc_test_provider_track_width.cpp
|
||||
drc_test_provider_annulus.cpp
|
||||
drc_test_provider_connectivity.cpp
|
||||
../../pcbnew/drc/drc_test_provider_hole_size.cpp
|
||||
../../pcbnew/drc/drc_test_provider_disallow.cpp
|
||||
../../pcbnew/drc/drc_test_provider_track_width.cpp
|
||||
../../pcbnew/drc/drc_test_provider_annulus.cpp
|
||||
../../pcbnew/drc/drc_test_provider_connectivity.cpp
|
||||
../../pcbnew/drc/drc_test_provider_courtyard_clearance.cpp
|
||||
drc_test_provider_via_diameter.cpp
|
||||
drc_test_provider_lvs.cpp
|
||||
drc_test_provider_misc.cpp
|
||||
../../pcbnew/drc/drc_test_provider_via_diameter.cpp
|
||||
../../pcbnew/drc/drc_test_provider_lvs.cpp
|
||||
../../pcbnew/drc/drc_test_provider_misc.cpp
|
||||
../../pcbnew/drc/drc_engine.cpp
|
||||
../../pcbnew/drc/drc_item.cpp
|
||||
../qa_utils/mocks.cpp
|
||||
|
@ -114,12 +113,3 @@ target_link_libraries( drc_proto
|
|||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
|
||||
${wxWidgets_LIBRARIES}
|
||||
)
|
||||
|
||||
# auto-generate drc_rules_lexer.h and drc_rules_keywords.cpp
|
||||
make_lexer(
|
||||
drc_proto
|
||||
drc_rules_proto.keywords
|
||||
drc_rules_proto_lexer.h
|
||||
drc_rules_proto_keywords.cpp
|
||||
DRCRULEPROTO_T
|
||||
)
|
||||
|
|
|
@ -1,285 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2020 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_PROVIDER__H
|
||||
#define DRC_PROVIDER__H
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_marker_pcb.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace test {
|
||||
|
||||
class DRC_ENGINE;
|
||||
|
||||
/**
|
||||
* DRC_TEST_PROVIDER
|
||||
* is a base class that represents a DRC "provider" which runs some DRC functions over a
|
||||
* #BOARD and spits out #PCB_MARKERs as needed.
|
||||
*/
|
||||
class DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
DRC_TEST_PROVIDER ( DRC_ENGINE *aDrc );
|
||||
virtual ~DRC_TEST_PROVIDER() {}
|
||||
|
||||
/**
|
||||
* Runs this provider against the given PCB with configured options (if any).
|
||||
*
|
||||
* Note: Board is non-const, as some DRC functions modify the board (e.g. zone fill
|
||||
* or polygon coalescing)
|
||||
*/
|
||||
virtual bool Run() = 0;
|
||||
|
||||
virtual void Enable( bool enable );
|
||||
virtual bool IsEnabled() const;
|
||||
|
||||
virtual const wxString GetName() const;
|
||||
virtual const wxString GetDescription() const;
|
||||
|
||||
virtual std::set<test::DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const;
|
||||
|
||||
/**
|
||||
* Pass a given marker to the marker handler
|
||||
*/
|
||||
virtual void HandleMarker( MARKER_PCB* aMarker ) const;
|
||||
|
||||
private:
|
||||
|
||||
DRC_ENGINE *m_drcEngine;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* BOARD_DRC_ITEMS_PROVIDER
|
||||
* is an implementation of the RC_ITEMS_PROVIDER interface which uses a BOARD instance
|
||||
* to fulfill the interface.
|
||||
*/
|
||||
class BOARD_DRC_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER
|
||||
{
|
||||
private:
|
||||
BOARD* m_board;
|
||||
|
||||
int m_severities;
|
||||
std::vector<MARKER_PCB*> m_filteredMarkers;
|
||||
|
||||
public:
|
||||
BOARD_DRC_ITEMS_PROVIDER( BOARD* aBoard ) :
|
||||
m_board( aBoard ),
|
||||
m_severities( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void SetSeverities( int aSeverities ) override
|
||||
{
|
||||
m_severities = aSeverities;
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
m_filteredMarkers.clear();
|
||||
|
||||
for( MARKER_PCB* marker : m_board->Markers() )
|
||||
{
|
||||
int markerSeverity;
|
||||
|
||||
if( marker->IsExcluded() )
|
||||
markerSeverity = RPT_SEVERITY_EXCLUSION;
|
||||
else
|
||||
markerSeverity = bds.GetSeverity( marker->GetRCItem()->GetErrorCode() );
|
||||
|
||||
if( markerSeverity & m_severities )
|
||||
m_filteredMarkers.push_back( marker );
|
||||
}
|
||||
}
|
||||
|
||||
int GetCount( int aSeverity = -1 ) override
|
||||
{
|
||||
if( aSeverity < 0 )
|
||||
return m_filteredMarkers.size();
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
int count = 0;
|
||||
|
||||
for( MARKER_PCB* marker : m_board->Markers() )
|
||||
{
|
||||
int markerSeverity;
|
||||
|
||||
if( marker->IsExcluded() )
|
||||
markerSeverity = RPT_SEVERITY_EXCLUSION;
|
||||
else
|
||||
markerSeverity = bds.GetSeverity( marker->GetRCItem()->GetErrorCode() );
|
||||
|
||||
if( markerSeverity == aSeverity )
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
DRC_ITEM* GetItem( int aIndex ) override
|
||||
{
|
||||
MARKER_PCB* marker = m_filteredMarkers[ aIndex ];
|
||||
|
||||
return marker ? static_cast<DRC_ITEM*>( marker->GetRCItem() ) : nullptr;
|
||||
}
|
||||
|
||||
void DeleteItem( int aIndex, bool aDeep ) override
|
||||
{
|
||||
MARKER_PCB* marker = m_filteredMarkers[ aIndex ];
|
||||
m_filteredMarkers.erase( m_filteredMarkers.begin() + aIndex );
|
||||
|
||||
if( aDeep )
|
||||
m_board->Delete( marker );
|
||||
}
|
||||
|
||||
void DeleteAllItems() override
|
||||
{
|
||||
m_board->DeleteMARKERs();
|
||||
m_filteredMarkers.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* VECTOR_DRC_ITEMS_PROVIDER
|
||||
* is an implementation of the interface named DRC_ITEMS_PROVIDER which uses a vector
|
||||
* of pointers to DRC_ITEMs to fulfill the interface. No ownership is taken of the
|
||||
* vector.
|
||||
*/
|
||||
class VECTOR_DRC_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER
|
||||
{
|
||||
PCB_BASE_FRAME* m_frame;
|
||||
std::vector<DRC_ITEM*>* m_sourceVector; // owns its DRC_ITEMs
|
||||
|
||||
int m_severities;
|
||||
std::vector<DRC_ITEM*> m_filteredVector; // does not own its DRC_ITEMs
|
||||
|
||||
public:
|
||||
|
||||
VECTOR_DRC_ITEMS_PROVIDER( PCB_BASE_FRAME* aFrame, std::vector<DRC_ITEM*>* aList ) :
|
||||
m_frame( aFrame ),
|
||||
m_sourceVector( aList ),
|
||||
m_severities( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void SetSeverities( int aSeverities ) override
|
||||
{
|
||||
m_severities = aSeverities;
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = m_frame->GetBoard()->GetDesignSettings();
|
||||
|
||||
m_filteredVector.clear();
|
||||
|
||||
if( m_sourceVector )
|
||||
{
|
||||
for( DRC_ITEM* item : *m_sourceVector )
|
||||
{
|
||||
if( bds.GetSeverity( item->GetErrorCode() ) & aSeverities )
|
||||
m_filteredVector.push_back( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GetCount( int aSeverity = -1 ) override
|
||||
{
|
||||
if( aSeverity < 0 )
|
||||
return m_filteredVector.size();
|
||||
|
||||
int count = 0;
|
||||
BOARD_DESIGN_SETTINGS& bds = m_frame->GetBoard()->GetDesignSettings();
|
||||
|
||||
if( m_sourceVector )
|
||||
{
|
||||
for( DRC_ITEM* item : *m_sourceVector )
|
||||
{
|
||||
if( bds.GetSeverity( item->GetErrorCode() ) == aSeverity )
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
DRC_ITEM* GetItem( int aIndex ) override
|
||||
{
|
||||
return (m_filteredVector)[aIndex];
|
||||
}
|
||||
|
||||
void DeleteItem( int aIndex, bool aDeep ) override
|
||||
{
|
||||
DRC_ITEM* item = m_filteredVector[aIndex];
|
||||
m_filteredVector.erase( m_filteredVector.begin() + aIndex );
|
||||
|
||||
if( aDeep )
|
||||
{
|
||||
for( size_t i = 0; i < m_sourceVector->size(); ++i )
|
||||
{
|
||||
if( m_sourceVector->at( i ) == item )
|
||||
{
|
||||
delete item;
|
||||
m_sourceVector->erase( m_sourceVector->begin() + i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteAllItems() override
|
||||
{
|
||||
if( m_sourceVector )
|
||||
{
|
||||
for( DRC_ITEM* item : *m_sourceVector )
|
||||
delete item;
|
||||
|
||||
m_sourceVector->clear();
|
||||
}
|
||||
|
||||
m_filteredVector.clear(); // no ownership of DRC_ITEM pointers
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* RATSNEST_DRC_ITEMS_PROVIDER
|
||||
*/
|
||||
class RATSNEST_DRC_ITEMS_PROVIDER : public VECTOR_DRC_ITEMS_PROVIDER
|
||||
{
|
||||
// TODO: for now this is just a vector, but we need to map it to some board-level
|
||||
// data-structure so that deleting/excluding things can do a deep delete/exclusion
|
||||
// which will be reflected in the ratsnest....
|
||||
public:
|
||||
RATSNEST_DRC_ITEMS_PROVIDER( PCB_BASE_FRAME* aFrame, std::vector<DRC_ITEM*>* aList ) :
|
||||
VECTOR_DRC_ITEMS_PROVIDER( aFrame, aList )
|
||||
{ }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // DRC_PROVIDER__H
|
|
@ -1,358 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020 CERN
|
||||
*
|
||||
* 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 3
|
||||
* 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-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef DRC_RTREE_H_
|
||||
#define DRC_RTREE_H_
|
||||
|
||||
#include <eda_rect.h>
|
||||
#include <class_board_item.h>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <geometry/rtree.h>
|
||||
#include <vector2d.h>
|
||||
|
||||
/**
|
||||
* DRC_RTREE -
|
||||
* Implements an R-tree for fast spatial and layer indexing of connectable items.
|
||||
* Non-owning.
|
||||
*/
|
||||
class DRC_RTREE
|
||||
{
|
||||
private:
|
||||
using drc_rtree = RTree<BOARD_ITEM*, int, 2, double>;
|
||||
|
||||
public:
|
||||
DRC_RTREE()
|
||||
{
|
||||
for( int layer : LSET::AllLayersMask().Seq() )
|
||||
m_tree[layer] = new drc_rtree();
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
~DRC_RTREE()
|
||||
{
|
||||
for( auto tree : m_tree )
|
||||
delete tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Insert()
|
||||
* Inserts an item into the tree. Item's bounding box is taken via its GetBoundingBox() method.
|
||||
*/
|
||||
void insert( BOARD_ITEM* aItem )
|
||||
{
|
||||
if( ZONE_CONTAINER* zone = dyn_cast<ZONE_CONTAINER*>( aItem ) )
|
||||
{
|
||||
for( int layer : zone->GetLayerSet().Seq() )
|
||||
{
|
||||
const SHAPE_POLY_SET& polyset = zone->GetFilledPolysList( PCB_LAYER_ID( layer ) );
|
||||
|
||||
for( int ii = 0; ii < polyset.TriangulatedPolyCount(); ++ii )
|
||||
{
|
||||
const auto poly = polyset.TriangulatedPolygon( ii );
|
||||
|
||||
for( int jj = 0; jj < poly->GetTriangleCount(); ++jj )
|
||||
{
|
||||
VECTOR2I a;
|
||||
VECTOR2I b;
|
||||
VECTOR2I c;
|
||||
poly->GetTriangle( jj, a, b, c );
|
||||
|
||||
const int mmin2[2] = { std::min( a.x, std::min( b.x, c.x ) ),
|
||||
std::min( a.y, std::min( b.y, c.y ) ) };
|
||||
const int mmax2[2] = { std::max( a.x, std::max( b.x, c.x ) ),
|
||||
std::max( a.y, std::max( b.y, c.y ) ) };
|
||||
|
||||
m_tree[layer]->Insert( mmin2, mmax2, aItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const EDA_RECT& bbox = aItem->GetBoundingBox();
|
||||
const int mmin[2] = { bbox.GetX(), bbox.GetY() };
|
||||
const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() };
|
||||
|
||||
for( int layer : aItem->GetLayerSet().Seq() )
|
||||
{
|
||||
m_tree[layer]->Insert( mmin, mmax, aItem );
|
||||
}
|
||||
}
|
||||
|
||||
m_count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Remove()
|
||||
* Removes an item from the tree. Removal is done by comparing pointers, attempting
|
||||
* to remove a copy of the item will fail.
|
||||
*/
|
||||
bool remove( BOARD_ITEM* aItem )
|
||||
{
|
||||
// First, attempt to remove the item using its given BBox
|
||||
const EDA_RECT& bbox = aItem->GetBoundingBox();
|
||||
const int mmin[2] = { bbox.GetX(), bbox.GetY() };
|
||||
const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() };
|
||||
bool removed = false;
|
||||
|
||||
for( auto layer : aItem->GetLayerSet().Seq() )
|
||||
{
|
||||
if( ZONE_CONTAINER* zone = dyn_cast<ZONE_CONTAINER*>( aItem ) )
|
||||
{
|
||||
// Continue removing the zone elements from the tree until they cannot be found
|
||||
while( !m_tree[int( layer )]->Remove( mmin, mmax, aItem ) )
|
||||
;
|
||||
|
||||
const int mmin2[2] = { INT_MIN, INT_MIN };
|
||||
const int mmax2[2] = { INT_MAX, INT_MAX };
|
||||
|
||||
// If we are not successful ( true == not found ), then we expand
|
||||
// the search to the full tree
|
||||
while( !m_tree[int( layer )]->Remove( mmin2, mmax2, aItem ) )
|
||||
;
|
||||
|
||||
// Loop to the next layer
|
||||
continue;
|
||||
}
|
||||
|
||||
// The non-zone search expects only a single element in the tree with the same
|
||||
// pointer aItem
|
||||
if( m_tree[int( layer )]->Remove( mmin, mmax, aItem ) )
|
||||
{
|
||||
// N.B. We must search the whole tree for the pointer to remove
|
||||
// because the item may have been moved before we have the chance to
|
||||
// delete it from the tree
|
||||
const int mmin2[2] = { INT_MIN, INT_MIN };
|
||||
const int mmax2[2] = { INT_MAX, INT_MAX };
|
||||
|
||||
if( m_tree[int( layer )]->Remove( mmin2, mmax2, aItem ) )
|
||||
continue;
|
||||
}
|
||||
|
||||
removed = true;
|
||||
}
|
||||
|
||||
m_count -= int( removed );
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function RemoveAll()
|
||||
* Removes all items from the RTree
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
for( auto tree : m_tree )
|
||||
tree->RemoveAll();
|
||||
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a given item exists in the tree. Note that this does not search the full tree
|
||||
* so if the item has been moved, this will return false when it should be true.
|
||||
*
|
||||
* @param aItem Item that may potentially exist in the tree
|
||||
* @param aRobust If true, search the whole tree, not just the bounding box
|
||||
* @return true if the item definitely exists, false if it does not exist within bbox
|
||||
*/
|
||||
bool contains( BOARD_ITEM* aItem, bool aRobust = false )
|
||||
{
|
||||
const EDA_RECT& bbox = aItem->GetBoundingBox();
|
||||
const int mmin[2] = { bbox.GetX(), bbox.GetY() };
|
||||
const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() };
|
||||
bool found = false;
|
||||
|
||||
auto search = [&found, &aItem]( const BOARD_ITEM* aSearchItem ) {
|
||||
if( aSearchItem == aItem )
|
||||
{
|
||||
found = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
for( int layer : aItem->GetLayerSet().Seq() )
|
||||
{
|
||||
m_tree[layer]->Search( mmin, mmax, search );
|
||||
|
||||
if( found )
|
||||
break;
|
||||
}
|
||||
|
||||
if( !found && aRobust )
|
||||
{
|
||||
for( int layer : LSET::AllCuMask().Seq() )
|
||||
{
|
||||
// N.B. We must search the whole tree for the pointer to remove
|
||||
// because the item may have been moved. We do not expand the item
|
||||
// layer search as this should not change.
|
||||
|
||||
const int mmin2[2] = { INT_MIN, INT_MIN };
|
||||
const int mmax2[2] = { INT_MAX, INT_MAX };
|
||||
|
||||
m_tree[layer]->Search( mmin2, mmax2, search );
|
||||
|
||||
if( found )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, BOARD_ITEM*>> GetNearest( const wxPoint &aPoint,
|
||||
PCB_LAYER_ID aLayer,
|
||||
int aLimit )
|
||||
{
|
||||
|
||||
const int point[2] = { aPoint.x, aPoint.y };
|
||||
auto result = m_tree[int( aLayer )]->NearestNeighbors( point,
|
||||
[aLimit]( std::size_t a_count, int a_maxDist ) -> bool
|
||||
{
|
||||
return a_count >= aLimit;
|
||||
},
|
||||
[]( BOARD_ITEM* aElement) -> bool
|
||||
{
|
||||
// Don't remove any elements from the list
|
||||
return false;
|
||||
},
|
||||
[aLayer]( const int* a_point, BOARD_ITEM* a_data ) -> int
|
||||
{
|
||||
switch( a_data->Type() )
|
||||
{
|
||||
case PCB_TRACE_T:
|
||||
{
|
||||
TRACK* track = static_cast<TRACK*>( a_data );
|
||||
SEG seg( track->GetStart(), track->GetEnd() );
|
||||
return seg.Distance( VECTOR2I( a_point[0], a_point[1] ) ) -
|
||||
( track->GetWidth() + 1 ) / 2;
|
||||
}
|
||||
case PCB_VIA_T:
|
||||
{
|
||||
VIA* via = static_cast<VIA*>( a_data );
|
||||
return ( VECTOR2I( via->GetPosition() ) -
|
||||
VECTOR2I( a_point[0], a_point[1] ) ).EuclideanNorm() -
|
||||
( via->GetWidth() + 1 ) / 2;
|
||||
|
||||
}
|
||||
default:
|
||||
{
|
||||
VECTOR2I point( a_point[0], a_point[1] );
|
||||
int dist = 0;
|
||||
auto shape = a_data->GetEffectiveShape( aLayer );
|
||||
|
||||
// Here we use a hack to get the distance by colliding with a large area
|
||||
// However, we can't use just MAX_INT because we will overflow the collision calculations
|
||||
shape->Collide( point, std::numeric_limits<int>::max() / 2, &dist);
|
||||
return dist;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of items in the tree
|
||||
* @return number of elements in the tree;
|
||||
*/
|
||||
size_t size()
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return m_count == 0;
|
||||
}
|
||||
|
||||
using iterator = typename drc_rtree::Iterator;
|
||||
|
||||
/**
|
||||
* The DRC_LAYER struct provides a layer-specific auto-range iterator to the RTree. Using
|
||||
* this struct, one can write lines like:
|
||||
*
|
||||
* for( auto item : rtree.OnLayer( In1_Cu ) )
|
||||
*
|
||||
* and iterate over only the RTree items that are on In1
|
||||
*/
|
||||
struct DRC_LAYER
|
||||
{
|
||||
DRC_LAYER( drc_rtree* aTree ) : layer_tree( aTree )
|
||||
{
|
||||
m_rect = { { INT_MIN, INT_MIN }, { INT_MAX, INT_MAX } };
|
||||
};
|
||||
|
||||
DRC_LAYER( drc_rtree* aTree, const EDA_RECT aRect ) : layer_tree( aTree )
|
||||
{
|
||||
m_rect = { { aRect.GetX(), aRect.GetY() },
|
||||
{ aRect.GetRight(), aRect.GetBottom() } };
|
||||
};
|
||||
|
||||
drc_rtree::Rect m_rect;
|
||||
drc_rtree* layer_tree;
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return layer_tree->begin( m_rect );
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return layer_tree->end( m_rect );
|
||||
}
|
||||
};
|
||||
|
||||
DRC_LAYER OnLayer( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
return DRC_LAYER( m_tree[int( aLayer )] );
|
||||
}
|
||||
|
||||
DRC_LAYER Overlapping( PCB_LAYER_ID aLayer, const wxPoint& aPoint, int aAccuracy = 0 )
|
||||
{
|
||||
EDA_RECT rect( aPoint, wxSize( 0, 0 ) );
|
||||
rect.Inflate( aAccuracy );
|
||||
return DRC_LAYER( m_tree[int( aLayer )], rect );
|
||||
}
|
||||
|
||||
DRC_LAYER Overlapping( PCB_LAYER_ID aLayer, const EDA_RECT& aRect )
|
||||
{
|
||||
return DRC_LAYER( m_tree[int( aLayer )], aRect );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
drc_rtree* m_tree[MAX_CU_LAYERS];
|
||||
size_t m_count;
|
||||
};
|
||||
|
||||
|
||||
#endif /* DRC_RTREE_H_ */
|
|
@ -1,50 +0,0 @@
|
|||
|
||||
/* Do not modify this file it was automatically generated by the
|
||||
* TokenList2DsnLexer CMake script.
|
||||
*
|
||||
* Include this file in your lexer class to provide the keywords for
|
||||
* your DSN lexer.
|
||||
*/
|
||||
|
||||
#include </home/twl/Kicad-dev/kicad-build/debug-dev/common/drc_rules_lexer.h>
|
||||
|
||||
using namespace DRCRULE_T;
|
||||
|
||||
#define TOKDEF(x) { #x, T_##x }
|
||||
|
||||
const KEYWORD DRC_RULES_LEXER::keywords[] = {
|
||||
TOKDEF( allow ),
|
||||
TOKDEF( condition ),
|
||||
TOKDEF( enable ),
|
||||
TOKDEF( error ),
|
||||
TOKDEF( expression ),
|
||||
TOKDEF( ignore ),
|
||||
TOKDEF( info ),
|
||||
TOKDEF( max ),
|
||||
TOKDEF( min ),
|
||||
TOKDEF( name ),
|
||||
TOKDEF( opt ),
|
||||
TOKDEF( priority ),
|
||||
TOKDEF( rule ),
|
||||
TOKDEF( severity ),
|
||||
TOKDEF( type ),
|
||||
TOKDEF( version ),
|
||||
TOKDEF( warning )
|
||||
};
|
||||
|
||||
const unsigned DRC_RULES_LEXER::keyword_count = unsigned( sizeof( DRC_RULES_LEXER::keywords )/sizeof( DRC_RULES_LEXER::keywords[0] ) );
|
||||
|
||||
|
||||
const char* DRC_RULES_LEXER::TokenName( T aTok )
|
||||
{
|
||||
const char* ret;
|
||||
|
||||
if( aTok < 0 )
|
||||
ret = DSNLEXER::Syntax( aTok );
|
||||
else if( (unsigned) aTok < keyword_count )
|
||||
ret = keywords[aTok].name;
|
||||
else
|
||||
ret = "token too big";
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
clearance
|
||||
condition
|
||||
constraint
|
||||
inner
|
||||
layer
|
||||
max
|
||||
min
|
||||
name
|
||||
opt
|
||||
outer
|
||||
allow
|
||||
rule
|
||||
version
|
||||
priority
|
||||
expression
|
||||
enable
|
||||
severity
|
||||
type
|
||||
error
|
||||
warning
|
||||
info
|
||||
ignore
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004-2020 KiCad Developers.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_track.h>
|
||||
#include <common.h>
|
||||
|
||||
#include <drc/drc_engine.h>
|
||||
#include <drc/drc.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_rule.h>
|
||||
#include <drc/drc_test_provider.h>
|
||||
|
||||
|
||||
/*
|
||||
Track width test. As the name says, checks width of the tracks (including segments and arcs)
|
||||
Errors generated:
|
||||
- DRCE_TRACK_WIDTH
|
||||
*/
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
class DRC_TEST_PROVIDER_TRACK_WIDTH : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
DRC_TEST_PROVIDER_TRACK_WIDTH()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~DRC_TEST_PROVIDER_TRACK_WIDTH()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Run() override;
|
||||
|
||||
virtual const wxString GetName() const override
|
||||
{
|
||||
return "width";
|
||||
};
|
||||
|
||||
virtual const wxString GetDescription() const override
|
||||
{
|
||||
return "Tests track widths";
|
||||
}
|
||||
|
||||
virtual std::set<DRC_CONSTRAINT_TYPE_T> GetMatchingConstraintIds() const override;
|
||||
};
|
||||
|
||||
}; // namespace test
|
||||
|
||||
|
||||
bool test::DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
|
||||
{
|
||||
if( !m_drcEngine->HasCorrectRulesForId( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH ) )
|
||||
{
|
||||
ReportAux( "No track width constraints found. Skipping check." );
|
||||
return false;
|
||||
}
|
||||
|
||||
ReportStage( ( "Testing track widths" ), 0, 2 );
|
||||
|
||||
auto checkTrackWidth = [&]( BOARD_ITEM* item ) -> bool {
|
||||
int width;
|
||||
VECTOR2I p0;
|
||||
|
||||
if( auto arc = dyn_cast<ARC*>( item ) )
|
||||
{
|
||||
width = arc->GetWidth();
|
||||
p0 = arc->GetStart();
|
||||
}
|
||||
else if( auto trk = dyn_cast<TRACK*>( item ) )
|
||||
{
|
||||
width = trk->GetWidth();
|
||||
p0 = ( trk->GetStart() + trk->GetEnd() ) / 2;
|
||||
}
|
||||
|
||||
DRC_CONSTRAINT constraint = m_drcEngine->EvalRulesForItems( DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH,
|
||||
item );
|
||||
|
||||
bool fail_min = false, fail_max = false;
|
||||
int constraintWidth;
|
||||
|
||||
if( constraint.Value().HasMin() && width < constraint.Value().Min() )
|
||||
{
|
||||
fail_min = true;
|
||||
constraintWidth = constraint.Value().Min();
|
||||
}
|
||||
|
||||
if( constraint.Value().HasMax() && width > constraint.Value().Max() )
|
||||
{
|
||||
fail_max = true;
|
||||
constraintWidth = constraint.Value().Max();
|
||||
}
|
||||
|
||||
if( fail_min || fail_max )
|
||||
{
|
||||
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TRACK_WIDTH );
|
||||
wxString msg;
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (%s; width %s, constraint %s %s)" ),
|
||||
constraint.GetParentRule()->m_Name,
|
||||
MessageTextFromValue( userUnits(), width, true ),
|
||||
fail_min ? _( "minimum" ) : _( "maximum" ),
|
||||
MessageTextFromValue( userUnits(), constraintWidth, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( item );
|
||||
drcItem->SetViolatingRule( constraint.GetParentRule() );
|
||||
|
||||
ReportWithMarker( drcItem, p0 );
|
||||
|
||||
if( isErrorLimitExceeded( DRCE_TRACK_WIDTH ) )
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
forEachGeometryItem( { PCB_TRACE_T, PCB_ARC_T }, LSET::AllCuMask(), checkTrackWidth );
|
||||
|
||||
reportRuleStatistics();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::set<DRC_CONSTRAINT_TYPE_T> test::DRC_TEST_PROVIDER_TRACK_WIDTH::GetMatchingConstraintIds() const
|
||||
{
|
||||
return { DRC_CONSTRAINT_TYPE_T::DRC_CONSTRAINT_TYPE_TRACK_WIDTH };
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
static DRC_REGISTER_TEST_PROVIDER<test::DRC_TEST_PROVIDER_TRACK_WIDTH> dummy;
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 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
|
||||
*/
|
||||
|
||||
|
||||
#include <drc/drc_textvar_tester.h>
|
||||
|
||||
#include <class_module.h>
|
||||
#include <class_pcb_text.h>
|
||||
#include <ws_draw_item.h>
|
||||
#include <ws_proxy_view_item.h>
|
||||
|
||||
DRC_TEXTVAR_TESTER::DRC_TEXTVAR_TESTER( MARKER_HANDLER aMarkerHandler,
|
||||
KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet ) :
|
||||
DRC_TEST_PROVIDER( std::move( aMarkerHandler ) ),
|
||||
m_units( EDA_UNITS::MILLIMETRES ),
|
||||
m_board( nullptr ),
|
||||
m_worksheet( aWorksheet )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool DRC_TEXTVAR_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
m_units = aUnits;
|
||||
m_board = &aBoard;
|
||||
|
||||
for( MODULE* module : m_board->Modules() )
|
||||
{
|
||||
module->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
if( child->Type() == PCB_MODULE_TEXT_T )
|
||||
{
|
||||
TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( child );
|
||||
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_UNRESOLVED_VARIABLE );
|
||||
drcItem->SetItems( text );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, text->GetPosition() ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
for( BOARD_ITEM* drawing : m_board->Drawings() )
|
||||
{
|
||||
if( drawing->Type() == PCB_TEXT_T )
|
||||
{
|
||||
TEXTE_PCB* text = static_cast<TEXTE_PCB*>( drawing );
|
||||
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_UNRESOLVED_VARIABLE );
|
||||
drcItem->SetItems( text );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, text->GetPosition() ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WS_DRAW_ITEM_LIST wsItems;
|
||||
|
||||
if( m_worksheet )
|
||||
{
|
||||
wsItems.SetMilsToIUfactor( IU_PER_MILS );
|
||||
wsItems.BuildWorkSheetGraphicList( m_worksheet->GetPageInfo(),
|
||||
m_worksheet->GetTitleBlock() );
|
||||
|
||||
for( WS_DRAW_ITEM_BASE* item = wsItems.GetFirst(); item; item = wsItems.GetNext() )
|
||||
{
|
||||
if( WS_DRAW_ITEM_TEXT* text = dynamic_cast<WS_DRAW_ITEM_TEXT*>( item ) )
|
||||
{
|
||||
if( text->GetShownText().Matches( wxT( "*${*}*" ) ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_UNRESOLVED_VARIABLE );
|
||||
drcItem->SetErrorMessage( _( "Unresolved text variable in worksheet." ) );
|
||||
|
||||
HandleMarker( new MARKER_PCB( drcItem, text->GetPosition() ) );
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JEY TODO: Test text vars in worksheet...
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 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
|
||||
* 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_TEXTVAR_TESTER__H
|
||||
#define DRC_TEXTVAR_TESTER__H
|
||||
|
||||
#include <drc/drc_results_provider.h>
|
||||
|
||||
|
||||
class BOARD;
|
||||
|
||||
|
||||
class DRC_TEXTVAR_TESTER : public DRC_TEST_PROVIDER
|
||||
{
|
||||
public:
|
||||
DRC_TEXTVAR_TESTER( MARKER_HANDLER aMarkerHandler, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet );
|
||||
|
||||
virtual ~DRC_TEXTVAR_TESTER() {};
|
||||
|
||||
bool RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) override;
|
||||
|
||||
private:
|
||||
EDA_UNITS m_units;
|
||||
BOARD* m_board;
|
||||
KIGFX::WS_PROXY_VIEW_ITEM* m_worksheet;
|
||||
};
|
||||
|
||||
#endif // DRC_TEXTVAR_TESTER__H
|
Loading…
Reference in New Issue