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:
parent
6be6680d8c
commit
6d85853365
include
pcbnew
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 );
|
||||
|
Loading…
Reference in New Issue
Block a user