mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-15 02:33:15 +02:00
Creepage : add minimum slot width
This commit is contained in:
parent
6be6680d8c
commit
6d85853365
@ -94,6 +94,7 @@
|
|||||||
#define LEGACY_COPPEREDGECLEARANCE -0.01 // A flag to indicate the legacy method (based
|
#define LEGACY_COPPEREDGECLEARANCE -0.01 // A flag to indicate the legacy method (based
|
||||||
// on edge cut line thicknesses) should be used.
|
// on edge cut line thicknesses) should be used.
|
||||||
#define DEFAULT_SILKCLEARANCE 0.0
|
#define DEFAULT_SILKCLEARANCE 0.0
|
||||||
|
#define DEFAULT_MINGROOVEWIDTH 0.0
|
||||||
|
|
||||||
#define DEFAULT_MINRESOLVEDSPOKES 2 // Fewer resolved spokes indicates a starved thermal
|
#define DEFAULT_MINRESOLVEDSPOKES 2 // Fewer resolved spokes indicates a starved thermal
|
||||||
|
|
||||||
@ -687,7 +688,8 @@ public:
|
|||||||
// connected track
|
// connected track
|
||||||
bool m_TempOverrideTrackWidth; // use selected track width temporarily even when
|
bool m_TempOverrideTrackWidth; // use selected track width temporarily even when
|
||||||
// using connected track width
|
// 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_MinConn; // overall min connection width
|
||||||
int m_TrackMinWidth; // overall min track width
|
int m_TrackMinWidth; // overall min track width
|
||||||
int m_ViasMinAnnularWidth; // overall minimum width of the via copper ring
|
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_MinResolvedSpokes = DEFAULT_MINRESOLVEDSPOKES;
|
||||||
m_MinSilkTextHeight = pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE * 0.8 );
|
m_MinSilkTextHeight = pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE * 0.8 );
|
||||||
m_MinSilkTextThickness= pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_WIDTH * 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 )
|
for( int errorCode = DRCE_FIRST; errorCode <= DRCE_LAST; ++errorCode )
|
||||||
m_DRCSeverities[ errorCode ] = RPT_SEVERITY_ERROR;
|
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 ),
|
&m_SilkClearance, pcbIUScale.mmToIU( DEFAULT_SILKCLEARANCE ),
|
||||||
pcbIUScale.mmToIU( 0.00 ), pcbIUScale.mmToIU( 100.0 ), pcbIUScale.MM_PER_IU ) );
|
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
|
// 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
|
// 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
|
// 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_UseConnectedTrackWidth = aOther.m_UseConnectedTrackWidth;
|
||||||
m_TempOverrideTrackWidth = aOther.m_TempOverrideTrackWidth;
|
m_TempOverrideTrackWidth = aOther.m_TempOverrideTrackWidth;
|
||||||
m_MinClearance = aOther.m_MinClearance;
|
m_MinClearance = aOther.m_MinClearance;
|
||||||
|
m_MinGrooveWidth = aOther.m_MinGrooveWidth;
|
||||||
m_MinConn = aOther.m_MinConn;
|
m_MinConn = aOther.m_MinConn;
|
||||||
m_TrackMinWidth = aOther.m_TrackMinWidth;
|
m_TrackMinWidth = aOther.m_TrackMinWidth;
|
||||||
m_ViasMinAnnularWidth = aOther.m_ViasMinAnnularWidth;
|
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_UseConnectedTrackWidth != aOther.m_UseConnectedTrackWidth ) return false;
|
||||||
if( m_TempOverrideTrackWidth != aOther.m_TempOverrideTrackWidth ) return false;
|
if( m_TempOverrideTrackWidth != aOther.m_TempOverrideTrackWidth ) return false;
|
||||||
if( m_MinClearance != aOther.m_MinClearance ) 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_MinConn != aOther.m_MinConn ) return false;
|
||||||
if( m_TrackMinWidth != aOther.m_TrackMinWidth ) return false;
|
if( m_TrackMinWidth != aOther.m_TrackMinWidth ) return false;
|
||||||
if( m_ViasMinAnnularWidth != aOther.m_ViasMinAnnularWidth ) return false;
|
if( m_ViasMinAnnularWidth != aOther.m_ViasMinAnnularWidth ) return false;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <widgets/paged_dialog.h>
|
#include <widgets/paged_dialog.h>
|
||||||
#include <wx/treebook.h>
|
#include <wx/treebook.h>
|
||||||
#include <bitmaps.h>
|
#include <bitmaps.h>
|
||||||
|
#include <advanced_config.h>
|
||||||
|
|
||||||
|
|
||||||
PANEL_SETUP_CONSTRAINTS::PANEL_SETUP_CONSTRAINTS( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame ) :
|
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_holeClearance( aFrame, m_HoleClearanceLabel, m_HoleClearanceCtrl, m_HoleClearanceUnits ),
|
||||||
m_edgeClearance( aFrame, m_EdgeClearanceLabel, m_EdgeClearanceCtrl, m_EdgeClearanceUnits ),
|
m_edgeClearance( aFrame, m_EdgeClearanceLabel, m_EdgeClearanceCtrl, m_EdgeClearanceUnits ),
|
||||||
m_silkClearance( aFrame, m_silkClearanceLabel, m_silkClearanceCtrl, m_silkClearanceUnits ),
|
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_minTextHeight( aFrame, m_textHeightLabel, m_textHeightCtrl, m_textHeightUnits ),
|
||||||
m_minTextThickness( aFrame, m_textThicknessLabel, m_textThicknessCtrl, m_textThicknessUnits ),
|
m_minTextThickness( aFrame, m_textThicknessLabel, m_textThicknessCtrl, m_textThicknessUnits ),
|
||||||
m_maxError( aFrame, m_maxErrorTitle, m_maxErrorCtrl, m_maxErrorUnits )
|
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();
|
wxSize ctrlSize = m_minResolvedSpokeCountCtrl->GetSize();
|
||||||
ctrlSize.x = KIUI::GetTextSize( wxT( "XXX" ), m_minResolvedSpokeCountCtrl ).x;
|
ctrlSize.x = KIUI::GetTextSize( wxT( "XXX" ), m_minResolvedSpokeCountCtrl ).x;
|
||||||
m_minResolvedSpokeCountCtrl->SetSize( ctrlSize );
|
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_viaMinSize.SetValue(m_BrdSettings->m_ViasMinSize );
|
||||||
m_holeClearance.SetValue( m_BrdSettings->m_HoleClearance );
|
m_holeClearance.SetValue( m_BrdSettings->m_HoleClearance );
|
||||||
m_edgeClearance.SetValue( m_BrdSettings->m_CopperEdgeClearance );
|
m_edgeClearance.SetValue( m_BrdSettings->m_CopperEdgeClearance );
|
||||||
|
m_minGrooveWidth.SetValue( m_BrdSettings->m_MinGrooveWidth );
|
||||||
|
|
||||||
m_throughHoleMin.SetValue( m_BrdSettings->m_MinThroughDrill );
|
m_throughHoleMin.SetValue( m_BrdSettings->m_MinThroughDrill );
|
||||||
m_holeToHoleMin.SetValue( m_BrdSettings->m_HoleToHoleMin );
|
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 ) )
|
if( !m_edgeClearance.Validate( 0, 10, EDA_UNITS::INCHES ) )
|
||||||
return false;
|
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
|
if( !m_throughHoleMin.Validate( 2, 1000, EDA_UNITS::MILS ) ) // #107 to 1 inch
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -159,6 +172,7 @@ bool PANEL_SETUP_CONSTRAINTS::TransferDataFromWindow()
|
|||||||
m_BrdSettings->m_ViasMinSize = m_viaMinSize.GetValue();
|
m_BrdSettings->m_ViasMinSize = m_viaMinSize.GetValue();
|
||||||
m_BrdSettings->m_HoleClearance = m_holeClearance.GetValue();
|
m_BrdSettings->m_HoleClearance = m_holeClearance.GetValue();
|
||||||
m_BrdSettings->m_CopperEdgeClearance = m_edgeClearance.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_MinThroughDrill = m_throughHoleMin.GetValue();
|
||||||
m_BrdSettings->m_HoleToHoleMin = m_holeToHoleMin.GetValue();
|
m_BrdSettings->m_HoleToHoleMin = m_holeToHoleMin.GetValue();
|
||||||
|
@ -60,6 +60,7 @@ public:
|
|||||||
UNIT_BINDER m_holeClearance;
|
UNIT_BINDER m_holeClearance;
|
||||||
UNIT_BINDER m_edgeClearance;
|
UNIT_BINDER m_edgeClearance;
|
||||||
UNIT_BINDER m_silkClearance;
|
UNIT_BINDER m_silkClearance;
|
||||||
|
UNIT_BINDER m_minGrooveWidth;
|
||||||
UNIT_BINDER m_minTextHeight;
|
UNIT_BINDER m_minTextHeight;
|
||||||
UNIT_BINDER m_minTextThickness;
|
UNIT_BINDER m_minTextThickness;
|
||||||
UNIT_BINDER m_maxError;
|
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/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
// 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 );
|
m_EdgeClearanceUnits->Wrap( -1 );
|
||||||
fgFeatureConstraints->Add( m_EdgeClearanceUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
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 );
|
m_staticline3 = new wxStaticLine( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||||
fgFeatureConstraints->Add( m_staticline3, 0, wxTOP|wxEXPAND, 10 );
|
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/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||||
@ -68,6 +68,10 @@ class PANEL_SETUP_CONSTRAINTS_BASE : public wxPanel
|
|||||||
wxStaticText* m_EdgeClearanceLabel;
|
wxStaticText* m_EdgeClearanceLabel;
|
||||||
wxTextCtrl* m_EdgeClearanceCtrl;
|
wxTextCtrl* m_EdgeClearanceCtrl;
|
||||||
wxStaticText* m_EdgeClearanceUnits;
|
wxStaticText* m_EdgeClearanceUnits;
|
||||||
|
wxStaticBitmap* m_bitmapMinGrooveWidth;
|
||||||
|
wxStaticText* m_minGrooveWidthLabel;
|
||||||
|
wxTextCtrl* m_minGrooveWidthCtrl;
|
||||||
|
wxStaticText* m_minGrooveWidthUnits;
|
||||||
wxStaticLine* m_staticline3;
|
wxStaticLine* m_staticline3;
|
||||||
wxStaticLine* m_staticline4;
|
wxStaticLine* m_staticline4;
|
||||||
wxStaticLine* m_staticline5;
|
wxStaticLine* m_staticline5;
|
||||||
|
@ -25,16 +25,15 @@
|
|||||||
#include <geometry/intersection.h>
|
#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,
|
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
|
//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 )
|
if( p1 == p2 || p1 == q2 || q1 == p2 || q1 == q2 )
|
||||||
return false;
|
return false;
|
||||||
@ -52,6 +51,13 @@ bool segments_intersect( VECTOR2I p1, VECTOR2I q1, VECTOR2I p2, VECTOR2I q2 )
|
|||||||
|
|
||||||
std::visit( visitor, geom1 );
|
std::visit( visitor, geom1 );
|
||||||
|
|
||||||
|
if( aIntersectPoints )
|
||||||
|
{
|
||||||
|
for( VECTOR2I& point : intersectionPoints )
|
||||||
|
aIntersectPoints->push_back( point );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return intersectionPoints.size() > 0;
|
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 ) )
|
for( path_connection pc : this->Paths( csp, aMaxWeight, aMaxSquaredWeight ) )
|
||||||
{
|
{
|
||||||
if( !segmentIntersectsArc( pc.a1, pc.a2, arcCenter, arcRadius, arcStartAngle,
|
if( !segmentIntersectsArc( pc.a1, pc.a2, arcCenter, arcRadius, arcStartAngle,
|
||||||
arcEndAngle ) )
|
arcEndAngle, nullptr ) )
|
||||||
result.push_back( pc );
|
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() );
|
double weight = abs( m_radius * ( angle2 - angle1 ).AsRadians() );
|
||||||
|
|
||||||
if( aG.m_minGrooveWidth <= 0 )
|
if( true || aG.m_minGrooveWidth <= 0 )
|
||||||
{
|
{
|
||||||
if( ( weight > aG.GetTarget() ) )
|
if( ( weight > aG.GetTarget() ) )
|
||||||
return;
|
return;
|
||||||
@ -824,7 +830,8 @@ void CreepageGraph::SetTarget( double aTarget )
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool segmentIntersectsArc( const VECTOR2I& p1, const VECTOR2I& p2, const VECTOR2I& center,
|
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 );
|
SEG segment( p1, p2 );
|
||||||
|
|
||||||
@ -840,6 +847,12 @@ bool segmentIntersectsArc( const VECTOR2I& p1, const VECTOR2I& p2, const VECTOR2
|
|||||||
INTERSECTION_VISITOR visitor( geom2, intersectionPoints );
|
INTERSECTION_VISITOR visitor( geom2, intersectionPoints );
|
||||||
std::visit( visitor, geom1 );
|
std::visit( visitor, geom1 );
|
||||||
|
|
||||||
|
if( aIntersectPoints )
|
||||||
|
{
|
||||||
|
for( VECTOR2I& point : intersectionPoints )
|
||||||
|
aIntersectPoints->push_back( point );
|
||||||
|
}
|
||||||
|
|
||||||
return intersectionPoints.size() > 0;
|
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 ) )
|
for( auto& pc : this->Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
|
||||||
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
||||||
beArcEndAngle ) )
|
beArcEndAngle, nullptr ) )
|
||||||
result.push_back( pc );
|
result.push_back( pc );
|
||||||
|
|
||||||
for( auto& pc : this->Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
|
for( auto& pc : this->Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
|
||||||
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
||||||
beArcEndAngle ) )
|
beArcEndAngle, nullptr ) )
|
||||||
result.push_back( pc );
|
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 ) )
|
for( auto& pc : this->Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
|
||||||
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
||||||
beArcEndAngle ) )
|
beArcEndAngle, nullptr ) )
|
||||||
result.push_back( pc );
|
result.push_back( pc );
|
||||||
|
|
||||||
for( auto& pc : this->Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
|
for( auto& pc : this->Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
|
||||||
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
||||||
beArcEndAngle ) )
|
beArcEndAngle, nullptr ) )
|
||||||
result.push_back( pc );
|
result.push_back( pc );
|
||||||
}
|
}
|
||||||
return result;
|
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 ) )
|
for( auto& pc : this->Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
|
||||||
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
||||||
beArcEndAngle ) )
|
beArcEndAngle, nullptr ) )
|
||||||
result.push_back( pc );
|
result.push_back( pc );
|
||||||
|
|
||||||
for( auto& pc : this->Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
|
for( auto& pc : this->Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
|
||||||
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
if( !segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle,
|
||||||
beArcEndAngle ) )
|
beArcEndAngle, nullptr ) )
|
||||||
result.push_back( pc );
|
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 );
|
SEG segment( p1, p2 );
|
||||||
CIRCLE circle( center, radius );
|
CIRCLE circle( center, radius );
|
||||||
@ -1730,13 +1744,26 @@ bool segmentIntersectsCircle( VECTOR2I p1, VECTOR2I p2, VECTOR2I center, double
|
|||||||
INTERSECTION_VISITOR visitor( geom2, intersectionPoints );
|
INTERSECTION_VISITOR visitor( geom2, intersectionPoints );
|
||||||
std::visit( visitor, geom1 );
|
std::visit( visitor, geom1 );
|
||||||
|
|
||||||
|
if( aIntersectPoints )
|
||||||
|
{
|
||||||
|
for( VECTOR2I& point : intersectionPoints )
|
||||||
|
{
|
||||||
|
aIntersectPoints->push_back( point );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return intersectionPoints.size() > 0;
|
return intersectionPoints.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
||||||
const std::vector<BOARD_ITEM*>& aBe,
|
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 )
|
for( BOARD_ITEM* be : aBe )
|
||||||
{
|
{
|
||||||
if( count( aDontTestAgainst.begin(), aDontTestAgainst.end(), be ) > 0 )
|
if( count( aDontTestAgainst.begin(), aDontTestAgainst.end(), be ) > 0 )
|
||||||
@ -1749,10 +1776,14 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
|||||||
switch( d->GetShape() )
|
switch( d->GetShape() )
|
||||||
{
|
{
|
||||||
case SHAPE_T::SEGMENT:
|
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;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case SHAPE_T::RECTANGLE:
|
case SHAPE_T::RECTANGLE:
|
||||||
{
|
{
|
||||||
VECTOR2I c1 = d->GetStart();
|
VECTOR2I c1 = d->GetStart();
|
||||||
@ -1760,9 +1791,13 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
|||||||
VECTOR2I c3 = d->GetEnd();
|
VECTOR2I c3 = d->GetEnd();
|
||||||
VECTOR2I c4( d->GetEnd().x, d->GetStart().y );
|
VECTOR2I c4( d->GetEnd().x, d->GetStart().y );
|
||||||
|
|
||||||
if( segments_intersect( aP1, aP2, c1, c2 ) || segments_intersect( aP1, aP2, c2, c3 )
|
bool intersects = false;
|
||||||
|| segments_intersect( aP1, aP2, c3, c4 )
|
intersects |= segments_intersect( aP1, aP2, c1, c2, &intersectionPoints );
|
||||||
|| segments_intersect( aP1, aP2, c4, c1 ) )
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1777,12 +1812,17 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
|||||||
break;
|
break;
|
||||||
VECTOR2I prevPoint = points.back();
|
VECTOR2I prevPoint = points.back();
|
||||||
|
|
||||||
|
bool intersects = false;
|
||||||
|
|
||||||
for( auto p : points )
|
for( auto p : points )
|
||||||
{
|
{
|
||||||
if( segments_intersect( aP1, aP2, prevPoint, p ) )
|
intersects |= segments_intersect( aP1, aP2, prevPoint, p, &intersectionPoints );
|
||||||
return false;
|
|
||||||
prevPoint = p;
|
prevPoint = p;
|
||||||
}
|
}
|
||||||
|
if( intersects && !TestGrooveWidth )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHAPE_T::CIRCLE:
|
case SHAPE_T::CIRCLE:
|
||||||
@ -1790,7 +1830,10 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
|||||||
VECTOR2I center = d->GetCenter();
|
VECTOR2I center = d->GetCenter();
|
||||||
double radius = d->GetRadius();
|
double radius = d->GetRadius();
|
||||||
|
|
||||||
if( segmentIntersectsCircle( aP1, aP2, center, radius ) )
|
bool intersects =
|
||||||
|
segmentIntersectsCircle( aP1, aP2, center, radius, &intersectionPoints );
|
||||||
|
|
||||||
|
if( intersects && !TestGrooveWidth )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1805,7 +1848,10 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
|||||||
EDA_ANGLE A, B;
|
EDA_ANGLE A, B;
|
||||||
d->CalcArcAngles( 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;
|
return false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1815,6 +1861,51 @@ bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
|||||||
default: break;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2225,7 +2316,7 @@ void CreepageGraph::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer,
|
|||||||
IgnoreForTest.push_back( gn2->m_parent->GetParent() );
|
IgnoreForTest.push_back( gn2->m_parent->GetParent() );
|
||||||
|
|
||||||
if( !pc.isValid( m_board, aLayer, m_boardEdge, IgnoreForTest, m_boardOutline,
|
if( !pc.isValid( m_board, aLayer, m_boardEdge, IgnoreForTest, m_boardOutline,
|
||||||
{ false, true } ) )
|
{ false, true }, m_minGrooveWidth ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
GraphNode* connect1;
|
GraphNode* connect1;
|
||||||
|
@ -47,9 +47,8 @@
|
|||||||
|
|
||||||
extern bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
extern bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
|
||||||
const std::vector<BOARD_ITEM*>& aBe,
|
const std::vector<BOARD_ITEM*>& aBe,
|
||||||
const std::vector<const BOARD_ITEM*>& aDontTestAgainst );
|
const std::vector<const BOARD_ITEM*>& aDontTestAgainst,
|
||||||
bool segmentIntersectsArc( const VECTOR2I& p1, const VECTOR2I& p2, const VECTOR2I& center,
|
int aMinGrooveWidth );
|
||||||
double radius, double startAngle, double endAngle );
|
|
||||||
|
|
||||||
struct path_connection
|
struct path_connection
|
||||||
{
|
{
|
||||||
@ -69,12 +68,12 @@ struct path_connection
|
|||||||
bool isValid( const BOARD& aBoard, PCB_LAYER_ID aLayer,
|
bool isValid( const BOARD& aBoard, PCB_LAYER_ID aLayer,
|
||||||
const std::vector<BOARD_ITEM*>& aBoardEdges,
|
const std::vector<BOARD_ITEM*>& aBoardEdges,
|
||||||
const std::vector<const BOARD_ITEM*>& aIgnoreForTest, SHAPE_POLY_SET* aOutline,
|
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 )
|
if( !aOutline )
|
||||||
return true; // We keep the segment if there is a problem
|
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;
|
return false;
|
||||||
|
|
||||||
// The mid point should be inside the board.
|
// The mid point should be inside the board.
|
||||||
|
@ -54,7 +54,7 @@ protected:
|
|||||||
BOARD* m_board;
|
BOARD* m_board;
|
||||||
bool m_boardOutlineValid;
|
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,
|
int aMarkerLayer, const BOARD_ITEM* aItem1,
|
||||||
const BOARD_ITEM* aItem2, PCB_LAYER_ID layer, int aDistance );
|
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();
|
const DRAWINGS drawings = m_board->Drawings();
|
||||||
CreepageGraph graph( *m_board );
|
CreepageGraph graph( *m_board );
|
||||||
|
graph.m_minGrooveWidth = m_board->GetDesignSettings().m_MinGrooveWidth;
|
||||||
graph.m_boardOutline = &outline;
|
graph.m_boardOutline = &outline;
|
||||||
|
|
||||||
this->CollectBoardEdges( graph.m_boardEdge );
|
this->CollectBoardEdges( graph.m_boardEdge );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user