7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 00:21:25 +00:00

Creepage : add minimum slot width

This commit is contained in:
Fabien Corona 2024-10-21 21:49:09 +02:00
parent 6be6680d8c
commit 6d85853365
11 changed files with 716 additions and 331 deletions

View File

@ -94,6 +94,7 @@
#define LEGACY_COPPEREDGECLEARANCE -0.01 // A flag to indicate the legacy method (based
// on edge cut line thicknesses) should be used.
#define DEFAULT_SILKCLEARANCE 0.0
#define DEFAULT_MINGROOVEWIDTH 0.0
#define DEFAULT_MINRESOLVEDSPOKES 2 // Fewer resolved spokes indicates a starved thermal
@ -687,7 +688,8 @@ public:
// connected track
bool m_TempOverrideTrackWidth; // use selected track width temporarily even when
// using connected track width
int m_MinClearance; // overall min clearance
int m_MinClearance; // overall min
int m_MinGrooveWidth; // Minimum groove width for creepage checks
int m_MinConn; // overall min connection width
int m_TrackMinWidth; // overall min track width
int m_ViasMinAnnularWidth; // overall minimum width of the via copper ring

View File

@ -156,6 +156,7 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
m_MinResolvedSpokes = DEFAULT_MINRESOLVEDSPOKES;
m_MinSilkTextHeight = pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE * 0.8 );
m_MinSilkTextThickness= pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_WIDTH * 0.8 );
m_MinGrooveWidth = pcbIUScale.mmToIU( DEFAULT_MINGROOVEWIDTH );
for( int errorCode = DRCE_FIRST; errorCode <= DRCE_LAST; ++errorCode )
m_DRCSeverities[ errorCode ] = RPT_SEVERITY_ERROR;
@ -283,6 +284,10 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
&m_SilkClearance, pcbIUScale.mmToIU( DEFAULT_SILKCLEARANCE ),
pcbIUScale.mmToIU( 0.00 ), pcbIUScale.mmToIU( 100.0 ), pcbIUScale.MM_PER_IU ) );
m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_groove_width",
&m_MinGrooveWidth, pcbIUScale.mmToIU( DEFAULT_MINGROOVEWIDTH ),
pcbIUScale.mmToIU( 0.00 ), pcbIUScale.mmToIU( 25.0 ), pcbIUScale.MM_PER_IU ) );
// While the maximum *effective* value is 4, we've had users interpret this as the count on
// all layers, and enter something like 10. They'll figure it out soon enough *unless* we
// enforce a max of 4 (and therefore reset it back to the default of 2), at which point it
@ -934,6 +939,7 @@ void BOARD_DESIGN_SETTINGS::initFromOther( const BOARD_DESIGN_SETTINGS& aOther )
m_UseConnectedTrackWidth = aOther.m_UseConnectedTrackWidth;
m_TempOverrideTrackWidth = aOther.m_TempOverrideTrackWidth;
m_MinClearance = aOther.m_MinClearance;
m_MinGrooveWidth = aOther.m_MinGrooveWidth;
m_MinConn = aOther.m_MinConn;
m_TrackMinWidth = aOther.m_TrackMinWidth;
m_ViasMinAnnularWidth = aOther.m_ViasMinAnnularWidth;
@ -1024,6 +1030,7 @@ bool BOARD_DESIGN_SETTINGS::operator==( const BOARD_DESIGN_SETTINGS& aOther ) co
if( m_UseConnectedTrackWidth != aOther.m_UseConnectedTrackWidth ) return false;
if( m_TempOverrideTrackWidth != aOther.m_TempOverrideTrackWidth ) return false;
if( m_MinClearance != aOther.m_MinClearance ) return false;
if( m_MinGrooveWidth != aOther.m_MinGrooveWidth ) return false;
if( m_MinConn != aOther.m_MinConn ) return false;
if( m_TrackMinWidth != aOther.m_TrackMinWidth ) return false;
if( m_ViasMinAnnularWidth != aOther.m_ViasMinAnnularWidth ) return false;

View File

@ -32,6 +32,7 @@
#include <widgets/paged_dialog.h>
#include <wx/treebook.h>
#include <bitmaps.h>
#include <advanced_config.h>
PANEL_SETUP_CONSTRAINTS::PANEL_SETUP_CONSTRAINTS( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame ) :
@ -48,6 +49,7 @@ PANEL_SETUP_CONSTRAINTS::PANEL_SETUP_CONSTRAINTS( wxWindow* aParentWindow, PCB_E
m_holeClearance( aFrame, m_HoleClearanceLabel, m_HoleClearanceCtrl, m_HoleClearanceUnits ),
m_edgeClearance( aFrame, m_EdgeClearanceLabel, m_EdgeClearanceCtrl, m_EdgeClearanceUnits ),
m_silkClearance( aFrame, m_silkClearanceLabel, m_silkClearanceCtrl, m_silkClearanceUnits ),
m_minGrooveWidth( aFrame, m_minGrooveWidthLabel, m_minGrooveWidthCtrl, m_minGrooveWidthUnits ),
m_minTextHeight( aFrame, m_textHeightLabel, m_textHeightCtrl, m_textHeightUnits ),
m_minTextThickness( aFrame, m_textThicknessLabel, m_textThicknessCtrl, m_textThicknessUnits ),
m_maxError( aFrame, m_maxErrorTitle, m_maxErrorCtrl, m_maxErrorUnits )
@ -74,6 +76,13 @@ PANEL_SETUP_CONSTRAINTS::PANEL_SETUP_CONSTRAINTS( wxWindow* aParentWindow, PCB_E
wxSize ctrlSize = m_minResolvedSpokeCountCtrl->GetSize();
ctrlSize.x = KIUI::GetTextSize( wxT( "XXX" ), m_minResolvedSpokeCountCtrl ).x;
m_minResolvedSpokeCountCtrl->SetSize( ctrlSize );
if( !ADVANCED_CFG::GetCfg().m_EnableCreepageDRC )
{
m_minGrooveWidthCtrl->Show( false );
m_minGrooveWidthUnits->Show( false );
m_minGrooveWidthLabel->Show( false );
}
}
@ -97,6 +106,7 @@ bool PANEL_SETUP_CONSTRAINTS::TransferDataToWindow()
m_viaMinSize.SetValue(m_BrdSettings->m_ViasMinSize );
m_holeClearance.SetValue( m_BrdSettings->m_HoleClearance );
m_edgeClearance.SetValue( m_BrdSettings->m_CopperEdgeClearance );
m_minGrooveWidth.SetValue( m_BrdSettings->m_MinGrooveWidth );
m_throughHoleMin.SetValue( m_BrdSettings->m_MinThroughDrill );
m_holeToHoleMin.SetValue( m_BrdSettings->m_HoleToHoleMin );
@ -135,6 +145,9 @@ bool PANEL_SETUP_CONSTRAINTS::TransferDataFromWindow()
if( !m_edgeClearance.Validate( 0, 10, EDA_UNITS::INCHES ) )
return false;
if( !m_minGrooveWidth.Validate( 0, 10, EDA_UNITS::INCHES ) )
return false;
if( !m_throughHoleMin.Validate( 2, 1000, EDA_UNITS::MILS ) ) // #107 to 1 inch
return false;
@ -159,6 +172,7 @@ bool PANEL_SETUP_CONSTRAINTS::TransferDataFromWindow()
m_BrdSettings->m_ViasMinSize = m_viaMinSize.GetValue();
m_BrdSettings->m_HoleClearance = m_holeClearance.GetValue();
m_BrdSettings->m_CopperEdgeClearance = m_edgeClearance.GetValue();
m_BrdSettings->m_MinGrooveWidth = m_minGrooveWidth.GetValue();
m_BrdSettings->m_MinThroughDrill = m_throughHoleMin.GetValue();
m_BrdSettings->m_HoleToHoleMin = m_holeToHoleMin.GetValue();

View File

@ -60,6 +60,7 @@ public:
UNIT_BINDER m_holeClearance;
UNIT_BINDER m_edgeClearance;
UNIT_BINDER m_silkClearance;
UNIT_BINDER m_minGrooveWidth;
UNIT_BINDER m_minTextHeight;
UNIT_BINDER m_minTextThickness;
UNIT_BINDER m_maxError;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -154,6 +154,22 @@ PANEL_SETUP_CONSTRAINTS_BASE::PANEL_SETUP_CONSTRAINTS_BASE( wxWindow* parent, wx
m_EdgeClearanceUnits->Wrap( -1 );
fgFeatureConstraints->Add( m_EdgeClearanceUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_bitmapMinGrooveWidth = new wxStaticBitmap( m_scrolledWindow, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
fgFeatureConstraints->Add( m_bitmapMinGrooveWidth, 0, wxALL, 5 );
m_minGrooveWidthLabel = new wxStaticText( m_scrolledWindow, wxID_ANY, _("Minimum groove for creepage:"), wxDefaultPosition, wxDefaultSize, 0 );
m_minGrooveWidthLabel->Wrap( -1 );
fgFeatureConstraints->Add( m_minGrooveWidthLabel, 0, wxALL, 5 );
m_minGrooveWidthCtrl = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_minGrooveWidthCtrl->SetToolTip( _("The minimum slot width from DRC creepage checks") );
fgFeatureConstraints->Add( m_minGrooveWidthCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND|wxTOP, 5 );
m_minGrooveWidthUnits = new wxStaticText( m_scrolledWindow, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_minGrooveWidthUnits->Wrap( -1 );
fgFeatureConstraints->Add( m_minGrooveWidthUnits, 0, wxALL, 5 );
m_staticline3 = new wxStaticLine( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
fgFeatureConstraints->Add( m_staticline3, 0, wxTOP|wxEXPAND, 10 );

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -68,6 +68,10 @@ class PANEL_SETUP_CONSTRAINTS_BASE : public wxPanel
wxStaticText* m_EdgeClearanceLabel;
wxTextCtrl* m_EdgeClearanceCtrl;
wxStaticText* m_EdgeClearanceUnits;
wxStaticBitmap* m_bitmapMinGrooveWidth;
wxStaticText* m_minGrooveWidthLabel;
wxTextCtrl* m_minGrooveWidthCtrl;
wxStaticText* m_minGrooveWidthUnits;
wxStaticLine* m_staticline3;
wxStaticLine* m_staticline4;
wxStaticLine* m_staticline5;

View File

@ -25,16 +25,15 @@
#include <geometry/intersection.h>
extern bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
const std::vector<BOARD_ITEM*>& aBe,
const std::vector<const BOARD_ITEM*>& aDontTestAgainst );
extern bool segmentIntersectsArc( const VECTOR2I& p1, const VECTOR2I& p2, const VECTOR2I& center,
double radius, EDA_ANGLE startAngle, EDA_ANGLE endAngle );
double radius, EDA_ANGLE startAngle, EDA_ANGLE endAngle,
std::vector<VECTOR2I>* aIntersectPoints );
//Check if line segments 'p1q1' and 'p2q2' intersect, excluding endpoint overlap
bool segments_intersect( VECTOR2I p1, VECTOR2I q1, VECTOR2I p2, VECTOR2I q2 )
bool segments_intersect( VECTOR2I p1, VECTOR2I q1, VECTOR2I p2, VECTOR2I q2,
std::vector<VECTOR2I>* aIntersectPoints )
{
if( p1 == p2 || p1 == q2 || q1 == p2 || q1 == q2 )
return false;
@ -52,6 +51,13 @@ bool segments_intersect( VECTOR2I p1, VECTOR2I q1, VECTOR2I p2, VECTOR2I q2 )
std::visit( visitor, geom1 );
if( aIntersectPoints )
{
for( VECTOR2I& point : intersectionPoints )
aIntersectPoints->push_back( point );
}
return intersectionPoints.size() > 0;
}
@ -332,7 +338,7 @@ std::vector<path_connection> BE_SHAPE_CIRCLE::Paths( const BE_SHAPE_ARC& aS2, do
for( path_connection pc : this->Paths( csp, aMaxWeight, aMaxSquaredWeight ) )
{
if( !segmentIntersectsArc( pc.a1, pc.a2, arcCenter, arcRadius, arcStartAngle,
arcEndAngle ) )
arcEndAngle, nullptr ) )
result.push_back( pc );
}
}
@ -797,7 +803,7 @@ void BE_SHAPE_ARC::ConnectChildren( GraphNode* a1, GraphNode* a2, CreepageGraph&
double weight = abs( m_radius * ( angle2 - angle1 ).AsRadians() );
if( aG.m_minGrooveWidth <= 0 )
if( true || aG.m_minGrooveWidth <= 0 )
{
if( ( weight > aG.GetTarget() ) )
return;
@ -824,7 +830,8 @@ void CreepageGraph::SetTarget( double aTarget )
}
bool segmentIntersectsArc( const VECTOR2I& p1, const VECTOR2I& p2, const VECTOR2I& center,
double radius, EDA_ANGLE startAngle, EDA_ANGLE endAngle )
double radius, EDA_ANGLE startAngle, EDA_ANGLE endAngle,
std::vector<VECTOR2I>* aIntersectPoints )
{
SEG segment( p1, p2 );
@ -840,6 +847,12 @@ bool segmentIntersectsArc( const VECTOR2I& p1, const VECTOR2I& p2, const VECTOR2
INTERSECTION_VISITOR visitor( geom2, intersectionPoints );
std::visit( visitor, geom1 );
if( aIntersectPoints )
{
for( VECTOR2I& point : intersectionPoints )
aIntersectPoints->push_back( point );
}
return intersectionPoints.size() > 0;
}
@ -1054,12 +1067,12 @@ std::vector<path_connection> CU_SHAPE_SEGMENT::Paths( const BE_SHAPE_ARC& aS2, d
for( auto& pc : this->Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
beArcEndAngle ) )
beArcEndAngle, nullptr ) )
result.push_back( pc );
for( auto& pc : this->Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
beArcEndAngle ) )
beArcEndAngle, nullptr ) )
result.push_back( pc );
}
@ -1095,12 +1108,12 @@ std::vector<path_connection> CU_SHAPE_CIRCLE::Paths( const BE_SHAPE_ARC& aS2, do
for( auto& pc : this->Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
beArcEndAngle ) )
beArcEndAngle, nullptr ) )
result.push_back( pc );
for( auto& pc : this->Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
beArcEndAngle ) )
beArcEndAngle, nullptr ) )
result.push_back( pc );
}
return result;
@ -1167,12 +1180,12 @@ std::vector<path_connection> CU_SHAPE_ARC::Paths( const BE_SHAPE_ARC& aS2, doubl
for( auto& pc : this->Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
beArcEndAngle ) )
beArcEndAngle, nullptr ) )
result.push_back( pc );
for( auto& pc : this->Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
beArcEndAngle ) )
beArcEndAngle, nullptr ) )
result.push_back( pc );
}
@ -1718,7 +1731,8 @@ std::vector<path_connection> CU_SHAPE_ARC::Paths( const CU_SHAPE_ARC& aS2, doubl
}
bool segmentIntersectsCircle( VECTOR2I p1, VECTOR2I p2, VECTOR2I center, double radius )
bool segmentIntersectsCircle( VECTOR2I p1, VECTOR2I p2, VECTOR2I center, double radius,
std::vector<VECTOR2I>* aIntersectPoints )
{
SEG segment( p1, p2 );
CIRCLE circle( center, radius );
@ -1730,13 +1744,26 @@ bool segmentIntersectsCircle( VECTOR2I p1, VECTOR2I p2, VECTOR2I center, double
INTERSECTION_VISITOR visitor( geom2, intersectionPoints );
std::visit( visitor, geom1 );
if( aIntersectPoints )
{
for( VECTOR2I& point : intersectionPoints )
{
aIntersectPoints->push_back( point );
}
}
return intersectionPoints.size() > 0;
}
bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
const std::vector<BOARD_ITEM*>& aBe,
const std::vector<const BOARD_ITEM*>& aDontTestAgainst )
const std::vector<const BOARD_ITEM*>& aDontTestAgainst,
int aMinGrooveWidth )
{
std::vector<VECTOR2I> intersectionPoints;
std::cout << "Path validation: " << ( (float) aMinGrooveWidth ) / 1e6 << std::endl;
bool TestGrooveWidth = aMinGrooveWidth > 0;
for( BOARD_ITEM* be : aBe )
{
if( count( aDontTestAgainst.begin(), aDontTestAgainst.end(), be ) > 0 )
@ -1749,10 +1776,14 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
switch( d->GetShape() )
{
case SHAPE_T::SEGMENT:
if( segments_intersect( aP1, aP2, d->GetStart(), d->GetEnd() ) )
{
bool intersects =
segments_intersect( aP1, aP2, d->GetStart(), d->GetEnd(), &intersectionPoints );
if( intersects && !TestGrooveWidth )
return false;
break;
}
case SHAPE_T::RECTANGLE:
{
VECTOR2I c1 = d->GetStart();
@ -1760,9 +1791,13 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
VECTOR2I c3 = d->GetEnd();
VECTOR2I c4( d->GetEnd().x, d->GetStart().y );
if( segments_intersect( aP1, aP2, c1, c2 ) || segments_intersect( aP1, aP2, c2, c3 )
|| segments_intersect( aP1, aP2, c3, c4 )
|| segments_intersect( aP1, aP2, c4, c1 ) )
bool intersects = false;
intersects |= segments_intersect( aP1, aP2, c1, c2, &intersectionPoints );
intersects |= segments_intersect( aP1, aP2, c2, c3, &intersectionPoints );
intersects |= segments_intersect( aP1, aP2, c3, c4, &intersectionPoints );
intersects |= segments_intersect( aP1, aP2, c4, c1, &intersectionPoints );
if( intersects && !TestGrooveWidth )
{
return false;
}
@ -1777,12 +1812,17 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
break;
VECTOR2I prevPoint = points.back();
bool intersects = false;
for( auto p : points )
{
if( segments_intersect( aP1, aP2, prevPoint, p ) )
return false;
intersects |= segments_intersect( aP1, aP2, prevPoint, p, &intersectionPoints );
prevPoint = p;
}
if( intersects && !TestGrooveWidth )
{
return false;
}
break;
}
case SHAPE_T::CIRCLE:
@ -1790,7 +1830,10 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
VECTOR2I center = d->GetCenter();
double radius = d->GetRadius();
if( segmentIntersectsCircle( aP1, aP2, center, radius ) )
bool intersects =
segmentIntersectsCircle( aP1, aP2, center, radius, &intersectionPoints );
if( intersects && !TestGrooveWidth )
return false;
break;
@ -1805,7 +1848,10 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
EDA_ANGLE A, B;
d->CalcArcAngles( A, B );
if( segmentIntersectsArc( aP1, aP2, center, radius, A, B ) )
bool intersects =
segmentIntersectsArc( aP1, aP2, center, radius, A, B, &intersectionPoints );
if( intersects && !TestGrooveWidth )
return false;
break;
@ -1815,6 +1861,51 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
default: break;
}
}
if( intersectionPoints.size() <= 0 )
return true;
if( intersectionPoints.size() % 2 != 0 )
return false; // Should not happen if the start and end are both on the board
int minx = intersectionPoints[0].x;
int maxx = intersectionPoints[0].x;
int miny = intersectionPoints[0].y;
int maxy = intersectionPoints[0].y;
for( VECTOR2I v : intersectionPoints )
{
minx = v.x < minx ? v.x : minx;
maxx = v.x > maxx ? v.x : maxx;
miny = v.x < miny ? v.x : miny;
maxy = v.x > maxy ? v.x : maxy;
}
if( abs( maxx - minx ) > abs( maxy - miny ) )
{
std::sort( intersectionPoints.begin(), intersectionPoints.end(),
[]( VECTOR2I a, VECTOR2I b )
{
return a.x > b.x;
} );
}
else
{
std::sort( intersectionPoints.begin(), intersectionPoints.end(),
[]( VECTOR2I a, VECTOR2I b )
{
return a.y > b.y;
} );
}
int GVSquared = aMinGrooveWidth * aMinGrooveWidth;
for( size_t i = 0; i < intersectionPoints.size(); i += 2 )
{
if( intersectionPoints[i].Distance( intersectionPoints[i + 1] ) > aMinGrooveWidth )
{
return false;
}
}
return true;
}
@ -2225,7 +2316,7 @@ void CreepageGraph::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer,
IgnoreForTest.push_back( gn2->m_parent->GetParent() );
if( !pc.isValid( m_board, aLayer, m_boardEdge, IgnoreForTest, m_boardOutline,
{ false, true } ) )
{ false, true }, m_minGrooveWidth ) )
continue;
GraphNode* connect1;

View File

@ -47,9 +47,8 @@
extern bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
const std::vector<BOARD_ITEM*>& aBe,
const std::vector<const BOARD_ITEM*>& aDontTestAgainst );
bool segmentIntersectsArc( const VECTOR2I& p1, const VECTOR2I& p2, const VECTOR2I& center,
double radius, double startAngle, double endAngle );
const std::vector<const BOARD_ITEM*>& aDontTestAgainst,
int aMinGrooveWidth );
struct path_connection
{
@ -69,12 +68,12 @@ struct path_connection
bool isValid( const BOARD& aBoard, PCB_LAYER_ID aLayer,
const std::vector<BOARD_ITEM*>& aBoardEdges,
const std::vector<const BOARD_ITEM*>& aIgnoreForTest, SHAPE_POLY_SET* aOutline,
const std::pair<bool, bool>& aTestLocalConcavity )
const std::pair<bool, bool>& aTestLocalConcavity, int aMinGrooveWidth )
{
if( !aOutline )
return true; // We keep the segment if there is a problem
if( !SegmentIntersectsBoard( a1, a2, aBoardEdges, aIgnoreForTest ) )
if( !SegmentIntersectsBoard( a1, a2, aBoardEdges, aIgnoreForTest, aMinGrooveWidth ) )
return false;
// The mid point should be inside the board.

View File

@ -54,7 +54,7 @@ protected:
BOARD* m_board;
bool m_boardOutlineValid;
void ReportAndShowPathCuToCu( std::shared_ptr<DRC_ITEM>& item, const VECTOR2I& aMarkerPos,
void ReportAndShowPathCuToCu( std::shared_ptr<DRC_ITEM>& aDrce, const VECTOR2I& aMarkerPos,
int aMarkerLayer, const BOARD_ITEM* aItem1,
const BOARD_ITEM* aItem2, PCB_LAYER_ID layer, int aDistance );

View File

@ -344,6 +344,7 @@ int DRC_TEST_PROVIDER_CREEPAGE::testCreepage()
const DRAWINGS drawings = m_board->Drawings();
CreepageGraph graph( *m_board );
graph.m_minGrooveWidth = m_board->GetDesignSettings().m_MinGrooveWidth;
graph.m_boardOutline = &outline;
this->CollectBoardEdges( graph.m_boardEdge );